*/
+#define __STDC_LIMIT_MACROS 1
+#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"
#include "audio_region_view.h"
#include "midi_region_view.h"
#include "ardour_ui.h"
+#include "gui_thread.h"
#include "control_point.h"
#include "utils.h"
#include "region_gain_line.h"
#include "canvas-note.h"
#include "selection.h"
#include "midi_selection.h"
+#include "automation_time_axis.h"
using namespace std;
using namespace ARDOUR;
using namespace PBD;
-using namespace sigc;
using namespace Gtk;
using namespace Editing;
using namespace ArdourCanvas;
double const ControlPointDrag::_zero_gain_fraction = gain_to_slider_position (dB_to_coefficient (0.0));
+DragManager::DragManager (Editor* e)
+ : _editor (e)
+ , _ending (false)
+ , _current_pointer_frame (0)
+{
+
+}
+
+DragManager::~DragManager ()
+{
+ abort ();
+}
+
+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 ();
+ delete *i;
+ }
+
+ _drags.clear ();
+
+ _ending = false;
+}
+
+void
+DragManager::add (Drag* d)
+{
+ d->set_manager (this);
+ _drags.push_back (d);
+}
+
+void
+DragManager::set (Drag* d, GdkEvent* e, Gdk::Cursor* c)
+{
+ assert (_drags.empty ());
+ d->set_manager (this);
+ _drags.push_back (d);
+ start_grab (e);
+}
+
+void
+DragManager::start_grab (GdkEvent* e)
+{
+ _current_pointer_frame = _editor->event_frame (e, &_current_pointer_x, &_current_pointer_y);
+
+ for (list<Drag*>::const_iterator i = _drags.begin(); i != _drags.end(); ++i) {
+ (*i)->start_grab (e);
+ }
+}
+
+bool
+DragManager::end_grab (GdkEvent* e)
+{
+ _ending = true;
+
+ bool r = false;
+ for (list<Drag*>::iterator i = _drags.begin(); i != _drags.end(); ++i) {
+ bool const t = (*i)->end_grab (e);
+ if (t) {
+ r = true;
+ }
+ delete *i;
+ }
+
+ _drags.clear ();
+
+ _ending = false;
+
+ return r;
+}
+
+bool
+DragManager::motion_handler (GdkEvent* e, bool from_autoscroll)
+{
+ bool r = false;
+
+ _current_pointer_frame = _editor->event_frame (e, &_current_pointer_x, &_current_pointer_y);
+
+ for (list<Drag*>::iterator i = _drags.begin(); i != _drags.end(); ++i) {
+ bool const t = (*i)->motion_handler (e, from_autoscroll);
+ if (t) {
+ r = true;
+ }
+
+ }
+
+ return r;
+}
+
+bool
+DragManager::have_item (ArdourCanvas::Item* i) const
+{
+ list<Drag*>::const_iterator j = _drags.begin ();
+ while (j != _drags.end() && (*j)->item () != i) {
+ ++j;
+ }
+
+ return j != _drags.end ();
+}
+
Drag::Drag (Editor* e, ArdourCanvas::Item* i)
: _editor (e)
, _item (i)
, _pointer_frame_offset (0)
+ , _move_threshold_passed (false)
, _grab_frame (0)
, _last_pointer_frame (0)
- , _current_pointer_frame (0)
- , _have_transaction (false)
- , _had_movement (false)
- , _move_threshold_passed (false)
{
}
}
_grab_frame = _editor->event_frame (event, &_grab_x, &_grab_y);
+ _grab_frame = adjusted_frame (_grab_frame, event);
_last_pointer_frame = _grab_frame;
- _current_pointer_frame = _grab_frame;
- _current_pointer_x = _grab_x;
- _current_pointer_y = _grab_y;
- _last_pointer_x = _current_pointer_x;
- _last_pointer_y = _current_pointer_y;
-
- _original_x = 0;
- _original_y = 0;
- _item->i2w (_original_x, _original_y);
+ _last_pointer_x = _grab_x;
+ _last_pointer_y = _grab_y;
_item->grab (Gdk::POINTER_MOTION_MASK|Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK,
*cursor,
event->button.time);
- if (_editor->session && _editor->session->transport_rolling()) {
+ if (_editor->session() && _editor->session()->transport_rolling()) {
_was_rolling = true;
} else {
_was_rolling = false;
bool
Drag::end_grab (GdkEvent* event)
{
- _ending = true;
-
_editor->stop_canvas_autoscroll ();
_item->ungrab (event ? event->button.time : 0);
- _last_pointer_x = _current_pointer_x;
- _last_pointer_y = _current_pointer_y;
- finished (event, _had_movement);
+ finished (event, _move_threshold_passed);
_editor->hide_verbose_canvas_cursor();
- _ending = false;
-
- return _had_movement;
+ return _move_threshold_passed;
}
nframes64_t
-Drag::adjusted_current_frame (GdkEvent* event) const
+Drag::adjusted_frame (nframes64_t f, GdkEvent const * event, bool snap) const
{
nframes64_t pos = 0;
- if (_current_pointer_frame > _pointer_frame_offset) {
- pos = _current_pointer_frame - _pointer_frame_offset;
+ if (f > _pointer_frame_offset) {
+ pos = f - _pointer_frame_offset;
}
- _editor->snap_to_with_modifier (pos, event);
+ if (snap) {
+ _editor->snap_to_with_modifier (pos, event);
+ }
return pos;
}
+nframes64_t
+Drag::adjusted_current_frame (GdkEvent const * event, bool snap) const
+{
+ return adjusted_frame (_drags->current_pointer_frame (), event, snap);
+}
+
bool
Drag::motion_handler (GdkEvent* event, bool from_autoscroll)
{
- _last_pointer_x = _current_pointer_x;
- _last_pointer_y = _current_pointer_y;
- _current_pointer_frame = _editor->event_frame (event, &_current_pointer_x, &_current_pointer_y);
-
- if (!from_autoscroll && !_move_threshold_passed) {
+ /* check to see if we have moved in any way that matters since the last motion event */
+ if ( (!x_movement_matters() || _last_pointer_frame == adjusted_current_frame (event)) &&
+ (!y_movement_matters() || _last_pointer_y == _drags->current_pointer_y ()) ) {
+ return false;
+ }
- bool const xp = (::llabs ((nframes64_t) (_current_pointer_x - _grab_x)) > 4LL);
- bool const yp = (::llabs ((nframes64_t) (_current_pointer_y - _grab_y)) > 4LL);
+ pair<nframes64_t, int> const threshold = move_threshold ();
- _move_threshold_passed = (xp || yp);
- }
+ bool const old_move_threshold_passed = _move_threshold_passed;
- bool old_had_movement = _had_movement;
+ if (!from_autoscroll && !_move_threshold_passed) {
- /* a motion event has happened, so we've had movement... */
- _had_movement = true;
+ bool const xp = (::llabs (adjusted_current_frame (event) - _grab_frame) >= threshold.first);
+ bool const yp = (::fabs ((_drags->current_pointer_y () - _grab_y)) >= threshold.second);
- /* ... unless we're using a move threshold and we've not yet passed it */
- if (apply_move_threshold() && !_move_threshold_passed) {
- _had_movement = false;
+ _move_threshold_passed = ((xp && x_movement_matters()) || (yp && y_movement_matters()));
}
- if (active (_editor->mouse_mode) && _had_movement) {
+ if (active (_editor->mouse_mode) && _move_threshold_passed) {
if (event->motion.state & Gdk::BUTTON1_MASK || event->motion.state & Gdk::BUTTON2_MASK) {
if (!from_autoscroll) {
_editor->maybe_autoscroll (&event->motion, allow_vertical_autoscroll ());
}
- motion (event, _had_movement != old_had_movement);
+ motion (event, _move_threshold_passed != old_move_threshold_passed);
+
+ _last_pointer_x = _drags->current_pointer_x ();
+ _last_pointer_y = _drags->current_pointer_y ();
+ _last_pointer_frame = adjusted_current_frame (event);
+
return true;
}
}
return false;
}
-
void
Drag::break_drag ()
{
- _editor->stop_canvas_autoscroll ();
- _editor->hide_verbose_canvas_cursor ();
-
if (_item) {
_item->ungrab (0);
+ }
- /* put it back where it came from */
+ aborted ();
- double cxw, cyw;
- cxw = 0;
- cyw = 0;
- _item->i2w (cxw, cyw);
- _item->move (_original_x - cxw, _original_y - cyw);
- }
+ _editor->stop_canvas_autoscroll ();
+ _editor->hide_verbose_canvas_cursor ();
}
-
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 (sigc::mem_fun (*this, &RegionDrag::region_going_away));
+ 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)
{
- _views.remove (v);
+ list<DraggingView>::iterator i = _views.begin ();
+ while (i != _views.end() && i->view != v) {
+ ++i;
+ }
+
+ if (i != _views.end()) {
+ _views.erase (i);
+ }
}
RegionMotionDrag::RegionMotionDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list<RegionView*> const & v, bool b)
: RegionDrag (e, i, p, v),
_dest_trackview (0),
_dest_layer (0),
- _brushing (b)
+ _brushing (b),
+ _total_x_delta (0)
{
}
/* get a bitmask representing the visible tracks */
- for (Editor::TrackViewList::iterator i = _editor->track_views.begin(); i != _editor->track_views.end(); ++i) {
+ for (TrackViewList::iterator i = _editor->track_views.begin(); i != _editor->track_views.end(); ++i) {
RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (*i);
TimeAxisView::Children children_list;
}
}
- 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;
double
RegionMotionDrag::compute_x_delta (GdkEvent const * event, nframes64_t* pending_region_position)
{
- *pending_region_position = 0;
-
/* compute the amount of pointer motion in frames, and where
the region would be if we moved it by that much.
*/
- if (_current_pointer_frame >= _pointer_frame_offset) {
-
- nframes64_t sync_frame;
- nframes64_t sync_offset;
- int32_t sync_dir;
-
- *pending_region_position = _current_pointer_frame - _pointer_frame_offset;
-
- sync_offset = _primary->region()->sync_offset (sync_dir);
-
- /* we don't handle a sync point that lies before zero.
- */
- if (sync_dir >= 0 || (sync_dir < 0 && *pending_region_position >= sync_offset)) {
-
- sync_frame = *pending_region_position + (sync_dir*sync_offset);
-
- _editor->snap_to_with_modifier (sync_frame, event);
-
- *pending_region_position = _primary->region()->adjust_to_sync (sync_frame);
-
- } else {
- *pending_region_position = _last_frame_position;
- }
-
+ *pending_region_position = adjusted_current_frame (event);
+
+ nframes64_t sync_frame;
+ nframes64_t sync_offset;
+ int32_t sync_dir;
+
+ sync_offset = _primary->region()->sync_offset (sync_dir);
+
+ /* we don't handle a sync point that lies before zero.
+ */
+ if (sync_dir >= 0 || (sync_dir < 0 && *pending_region_position >= sync_offset)) {
+
+ sync_frame = *pending_region_position + (sync_dir*sync_offset);
+
+ _editor->snap_to_with_modifier (sync_frame, event);
+
+ *pending_region_position = _primary->region()->adjust_to_sync (sync_frame);
+
+ } else {
+ *pending_region_position = _last_frame_position;
}
if (*pending_region_position > max_frames - _primary->region()->length()) {
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.
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;
} /* foreach region */
+ _total_x_delta += x_delta;
+
if (first_move) {
_editor->cursor_group->raise_to_top();
}
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);
}
}
}
}
- _have_transaction = true;
-
changed_position = (_last_frame_position != (nframes64_t) (_primary->region()->position()));
changed_tracks = (_dest_trackview != &_primary->get_time_axis_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";
+
+ for (list<DraggingView>::const_iterator i = _views.begin(); i != _views.end(); ) {
- RegionView* rv = (*i);
- RouteTimeAxisView* dest_rtv = final[*i].first;
- layer_t dest_layer = final[*i].second;
+ 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);
}
+
+ /* freeze playlist to avoid lots of relayering in the case of a multi-region drag */
- insert_result = modified_playlists.insert (playlist);
-
- if (insert_result.second) {
- _editor->session->add_command (new MementoCommand<Playlist>(*playlist, &playlist->get_state(), 0));
- }
- /* freeze to avoid lots of relayering in the case of a multi-region drag */
frozen_insert_result = frozen_playlists.insert(playlist);
if (frozen_insert_result.second) {
playlist->freeze();
}
+ cerr << "Moving region " << rv->region()->id() << endl;
+
rv->region()->set_position (where, (void*) this);
+
+ 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 ();
}
}
+void
+RegionMoveDrag::aborted ()
+{
+ if (_copy) {
+
+ for (list<DraggingView>::const_iterator i = _views.begin(); i != _views.end(); ++i) {
+ delete i->view;
+ }
+
+ _views.clear ();
+
+ } else {
+ RegionMotionDrag::aborted ();
+ }
+}
+
+void
+RegionMotionDrag::aborted ()
+{
+ 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);
+ 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 ();
+}
+
bool
RegionMotionDrag::x_move_allowed () const
{
/* 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
without it, the canvas seems to
"forget" to update properly after the upcoming reparent()
..only if the mouse is in rapid motion at the time of the grab.
- something to do with regionview creation raking so long?
+ something to do with regionview creation taking so long?
*/
_editor->update_canvas_now();
}
{
/* Which trackview is this ? */
- pair<TimeAxisView*, int> const tvp = _editor->trackview_by_y_position (current_pointer_y ());
+ pair<TimeAxisView*, int> const tvp = _editor->trackview_by_y_position (_drags->current_pointer_y ());
(*tv) = dynamic_cast<RouteTimeAxisView*> (tvp.first);
(*layer) = tvp.second;
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);
{
RegionMotionDrag::start_grab (event, c);
- _pointer_frame_offset = _grab_frame - _last_frame_position;
+ _pointer_frame_offset = grab_frame() - _last_frame_position;
}
RegionInsertDrag::RegionInsertDrag (Editor* e, boost::shared_ptr<Region> r, RouteTimeAxisView* v, nframes64_t pos)
_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;
_views.clear ();
}
+void
+RegionInsertDrag::aborted ()
+{
+ /* XXX: TODO */
+}
+
RegionSpliceDrag::RegionSpliceDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list<RegionView*> const & v)
: RegionMoveDrag (e, i, p, v, false, false)
{
};
void
-RegionSpliceDrag::motion (GdkEvent* /*event*/, bool)
+RegionSpliceDrag::motion (GdkEvent* event, bool)
{
RouteTimeAxisView* tv;
layer_t layer;
int dir;
- if (_current_pointer_x - _grab_x > 0) {
+ if ((_drags->current_pointer_x() - last_pointer_x()) > 0) {
dir = 1;
} else {
dir = -1;
RegionSelectionByPosition cmp;
copy.sort (cmp);
+ nframes64_t const pf = adjusted_current_frame (event);
+
for (RegionSelection::iterator i = copy.begin(); i != copy.end(); ++i) {
RouteTimeAxisView* atv = dynamic_cast<RouteTimeAxisView*> (&(*i)->get_time_axis_view());
}
if (dir > 0) {
- if (_current_pointer_frame < (*i)->region()->last_frame() + 1) {
+ if (pf < (*i)->region()->last_frame() + 1) {
continue;
}
} else {
- if (_current_pointer_frame > (*i)->region()->first_frame()) {
+ if (pf > (*i)->region()->first_frame()) {
continue;
}
}
playlist->shuffle ((*i)->region(), dir);
-
- _grab_x = _current_pointer_x;
}
}
}
+void
+RegionSpliceDrag::aborted ()
+{
+ /* XXX: TODO */
+}
RegionCreateDrag::RegionCreateDrag (Editor* e, ArdourCanvas::Item* i, TimeAxisView* v)
: Drag (e, i),
}
if (!movement_occurred) {
- mtv->add_region (_grab_frame);
+ mtv->add_region (grab_frame ());
} else {
motion (event, false);
// TODO: create region-create-drag region here
}
}
+void
+RegionCreateDrag::aborted ()
+{
+ /* XXX: TODO */
+}
+
NoteResizeDrag::NoteResizeDrag (Editor* e, ArdourCanvas::Item* i)
: Drag (e, i)
, region (0)
double region_start = region->get_position_pixels();
double middle_point = region_start + cnote->x1() + (cnote->x2() - cnote->x1()) / 2.0L;
- if (_grab_x <= middle_point) {
+ if (grab_x() <= middle_point) {
cursor = Gdk::Cursor(Gdk::LEFT_SIDE);
at_front = true;
} else {
{
MidiRegionSelection& ms (_editor->get_selection().midi_regions);
for (MidiRegionSelection::iterator r = ms.begin(); r != ms.end(); ++r) {
- (*r)->update_resizing (at_front, _current_pointer_x - _grab_x, relative);
+ (*r)->update_resizing (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, _current_pointer_x - _grab_x, relative);
+ (*r)->commit_resizing (at_front, _drags->current_pointer_x() - grab_x(), relative);
}
}
+void
+NoteResizeDrag::aborted ()
+{
+ /* XXX: TODO */
+}
+
void
RegionGainDrag::motion (GdkEvent* /*event*/, bool)
{
}
+void
+RegionGainDrag::aborted ()
+{
+ /* XXX: TODO */
+}
+
TrimDrag::TrimDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list<RegionView*> const & v)
: RegionDrag (e, i, p, v)
+ , _have_transaction (false)
{
}
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);
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;
} else {
/* These will get overridden for a point trim.*/
- if (_current_pointer_frame < (region_start + region_length/2)) {
+ if (pf < (region_start + region_length/2)) {
/* closer to start */
_operation = StartTrim;
- } else if (_current_pointer_frame > (region_end - region_length/2)) {
+ } else if (pf > (region_end - region_length/2)) {
/* closer to end */
_operation = EndTrim;
}
_editor->show_verbose_time_cursor (region_end, 10);
break;
case ContentsTrim:
- _editor->show_verbose_time_cursor (_current_pointer_frame, 10);
+ _editor->show_verbose_time_cursor (pf, 10);
break;
}
}
nframes64_t frame_delta = 0;
bool left_direction;
- bool obey_snap = !Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier());
+ 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
+ its current state has to be passed to the
various trim functions in order to work properly
*/
pair<set<boost::shared_ptr<Playlist> >::iterator,bool> insert_result;
if (tv && tv->is_track()) {
- speed = tv->get_diskstream()->speed();
+ speed = tv->track()->speed();
}
- if (_last_pointer_frame > _current_pointer_frame) {
+ nframes64_t const pf = adjusted_current_frame (event);
+
+ if (last_pointer_frame() > pf) {
left_direction = true;
} else {
left_direction = false;
}
- _editor->snap_to_with_modifier (_current_pointer_frame, event);
-
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 (_current_pointer_frame == _last_pointer_frame) {
- return;
- }
-
- /* XXX i hope to god that we can really conclude this ... */
- _have_transaction = true;
-
if (left_direction) {
- frame_delta = (_last_pointer_frame - _current_pointer_frame);
+ frame_delta = (last_pointer_frame() - pf);
} else {
- frame_delta = (_current_pointer_frame - _last_pointer_frame);
+ frame_delta = (pf - last_pointer_frame());
}
bool non_overlap_trim = false;
- if (Keyboard::modifier_state_equals (event->button.state, Keyboard::TertiaryModifier)) {
+ if (event && Keyboard::modifier_state_equals (event->button.state, Keyboard::TertiaryModifier)) {
non_overlap_trim = true;
}
switch (_operation) {
case StartTrim:
- if ((left_direction == false) && (_current_pointer_frame <= rv->region()->first_frame()/speed)) {
+ 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);
+ for (list<DraggingView>::const_iterator i = _views.begin(); i != _views.end(); ++i) {
+ _editor->single_start_trim (*i->view, frame_delta, left_direction, obey_snap, non_overlap_trim);
}
break;
}
case EndTrim:
- if ((left_direction == true) && (_current_pointer_frame > (nframes64_t) (rv->region()->last_frame()/speed))) {
+ 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);
+ for (list<DraggingView>::const_iterator i = _views.begin(); i != _views.end(); ++i) {
+ _editor->single_end_trim (*i->view, frame_delta, left_direction, obey_snap, non_overlap_trim);
}
break;
}
{
bool swap_direction = false;
- if (Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) {
+ if (event && Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) {
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);
+ for (list<DraggingView>::const_iterator i = _views.begin(); i != _views.end(); ++i) {
+ _editor->single_contents_trim (*i->view, frame_delta, left_direction, swap_direction, obey_snap);
}
}
break;
_editor->show_verbose_time_cursor((nframes64_t) (rv->region()->last_frame()/speed), 10);
break;
case ContentsTrim:
- _editor->show_verbose_time_cursor(_current_pointer_frame, 10);
+ _editor->show_verbose_time_cursor (pf, 10);
break;
}
-
- _last_pointer_frame = _current_pointer_frame;
}
_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 ();
} else {
/* no mouse movement */
- _editor->point_trim (event);
+ _editor->point_trim (event, adjusted_current_frame (event));
+ }
+}
+
+void
+TrimDrag::aborted ()
+{
+ /* Our motion method is changing model state, so use the Undo system
+ to cancel. Perhaps not ideal, as this will leave an Undo point
+ behind which may be slightly odd from the user's point of view.
+ */
+
+ finished (0, true);
+
+ if (_have_transaction) {
+ _editor->undo ();
}
}
Drag::start_grab (event, cursor);
- _pointer_frame_offset = _grab_frame - _marker->meter().frame();
+ _pointer_frame_offset = grab_frame() - _marker->meter().frame();
- _editor->show_verbose_time_cursor (_current_pointer_frame, 10);
+ _editor->show_verbose_time_cursor (adjusted_current_frame(event), 10);
}
void
MeterMarkerDrag::motion (GdkEvent* event, bool)
{
- nframes64_t const adjusted_frame = adjusted_current_frame (event);
-
- if (adjusted_frame == _last_pointer_frame) {
- return;
- }
-
- _marker->set_position (adjusted_frame);
+ nframes64_t const pf = adjusted_current_frame (event);
- _last_pointer_frame = adjusted_frame;
-
- _editor->show_verbose_time_cursor (adjusted_frame, 10);
+ _marker->set_position (pf);
+
+ _editor->show_verbose_time_cursor (pf, 10);
}
void
BBT_Time when;
- TempoMap& map (_editor->session->tempo_map());
- map.bbt_time (_last_pointer_frame, when);
+ TempoMap& map (_editor->session()->tempo_map());
+ map.bbt_time (last_pointer_frame(), when);
if (_copy == true) {
_editor->begin_reversible_command (_("copy meter mark"));
XMLNode &before = map.get_state();
map.add_meter (_marker->meter(), when);
XMLNode &after = map.get_state();
- _editor->session->add_command(new MementoCommand<TempoMap>(map, &before, &after));
+ _editor->session()->add_command(new MementoCommand<TempoMap>(map, &before, &after));
_editor->commit_reversible_command ();
// delete the dummy marker we used for visual representation of copying.
XMLNode &before = map.get_state();
map.move_meter (_marker->meter(), when);
XMLNode &after = map.get_state();
- _editor->session->add_command(new MementoCommand<TempoMap>(map, &before, &after));
+ _editor->session()->add_command(new MementoCommand<TempoMap>(map, &before, &after));
_editor->commit_reversible_command ();
}
}
+void
+MeterMarkerDrag::aborted ()
+{
+ _marker->set_position (_marker->meter().frame ());
+}
+
TempoMarkerDrag::TempoMarkerDrag (Editor* e, ArdourCanvas::Item* i, bool c)
: Drag (e, i),
_copy (c)
Drag::start_grab (event, cursor);
- _pointer_frame_offset = _grab_frame - _marker->tempo().frame();
- _editor->show_verbose_time_cursor (_current_pointer_frame, 10);
+ _pointer_frame_offset = grab_frame() - _marker->tempo().frame();
+ _editor->show_verbose_time_cursor (adjusted_current_frame (event), 10);
}
void
TempoMarkerDrag::motion (GdkEvent* event, bool)
{
- nframes64_t const adjusted_frame = adjusted_current_frame (event);
-
- if (adjusted_frame == _last_pointer_frame) {
- return;
- }
-
- /* OK, we've moved far enough to make it worth actually move the thing. */
-
- _marker->set_position (adjusted_frame);
-
- _editor->show_verbose_time_cursor (adjusted_frame, 10);
-
- _last_pointer_frame = adjusted_frame;
+ nframes64_t const pf = adjusted_current_frame (event);
+ _marker->set_position (pf);
+ _editor->show_verbose_time_cursor (pf, 10);
}
void
BBT_Time when;
- TempoMap& map (_editor->session->tempo_map());
- map.bbt_time (_last_pointer_frame, when);
+ TempoMap& map (_editor->session()->tempo_map());
+ map.bbt_time (last_pointer_frame(), when);
if (_copy == true) {
_editor->begin_reversible_command (_("copy tempo mark"));
XMLNode &before = map.get_state();
map.add_tempo (_marker->tempo(), when);
XMLNode &after = map.get_state();
- _editor->session->add_command (new MementoCommand<TempoMap>(map, &before, &after));
+ _editor->session()->add_command (new MementoCommand<TempoMap>(map, &before, &after));
_editor->commit_reversible_command ();
// delete the dummy marker we used for visual representation of copying.
XMLNode &before = map.get_state();
map.move_tempo (_marker->tempo(), when);
XMLNode &after = map.get_state();
- _editor->session->add_command (new MementoCommand<TempoMap>(map, &before, &after));
+ _editor->session()->add_command (new MementoCommand<TempoMap>(map, &before, &after));
_editor->commit_reversible_command ();
}
}
+void
+TempoMarkerDrag::aborted ()
+{
+ _marker->set_position (_marker->tempo().frame());
+}
CursorDrag::CursorDrag (Editor* e, ArdourCanvas::Item* i, bool s)
: Drag (e, i),
if (_cursor == _editor->playhead_cursor) {
_editor->_dragging_playhead = true;
- if (_editor->session && _was_rolling && _stop) {
- _editor->session->request_stop ();
+ if (_editor->session() && _was_rolling && _stop) {
+ _editor->session()->request_stop ();
}
- if (_editor->session && _editor->session->is_auditioning()) {
- _editor->session->cancel_audition ();
+ if (_editor->session() && _editor->session()->is_auditioning()) {
+ _editor->session()->cancel_audition ();
}
}
+ _pointer_frame_offset = grab_frame() - _cursor->current_frame;
+
_editor->show_verbose_time_cursor (_cursor->current_frame, 10);
}
{
nframes64_t const adjusted_frame = adjusted_current_frame (event);
- if (adjusted_frame == _last_pointer_frame) {
+ if (adjusted_frame == last_pointer_frame()) {
return;
}
_editor->update_canvas_now ();
#endif
_editor->UpdateAllTransportClocks (_cursor->current_frame);
-
- _last_pointer_frame = adjusted_frame;
}
void
motion (event, false);
if (_item == &_editor->playhead_cursor->canvas_item) {
- if (_editor->session) {
- _editor->session->request_locate (_editor->playhead_cursor->current_frame, _was_rolling);
+ if (_editor->session()) {
+ _editor->session()->request_locate (_editor->playhead_cursor->current_frame, _was_rolling);
_editor->_pending_locate_request = true;
}
}
}
+void
+CursorDrag::aborted ()
+{
+ _editor->_dragging_playhead = false;
+ _cursor->set_position (adjusted_frame (grab_frame (), 0, false));
+}
+
FadeInDrag::FadeInDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list<RegionView*> const & v)
: RegionDrag (e, i, p, v)
{
AudioRegionView* a = dynamic_cast<AudioRegionView*> (_primary);
boost::shared_ptr<AudioRegion> const r = a->audio_region ();
- _pointer_frame_offset = _grab_frame - ((nframes64_t) r->fade_in()->back()->when + r->position());
+ _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);
}
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;
tmp->audio_region()->set_fade_in_active (true);
XMLNode &after = alist->get_state();
- _editor->session->add_command(new MementoCommand<AutomationList>(*alist.get(), &before, &after));
+ _editor->session()->add_command(new MementoCommand<AutomationList>(*alist.get(), &before, &after));
}
_editor->commit_reversible_command ();
}
+void
+FadeInDrag::aborted ()
+{
+ for (list<DraggingView>::iterator i = _views.begin(); i != _views.end(); ++i) {
+ AudioRegionView* tmp = dynamic_cast<AudioRegionView*> (i->view);
+
+ if (!tmp) {
+ continue;
+ }
+
+ tmp->reset_fade_in_shape_width (tmp->audio_region()->fade_in()->back()->when);
+ }
+}
+
FadeOutDrag::FadeOutDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list<RegionView*> const & v)
: RegionDrag (e, i, p, v)
{
AudioRegionView* a = dynamic_cast<AudioRegionView*> (_primary);
boost::shared_ptr<AudioRegion> r = a->audio_region ();
- _pointer_frame_offset = _grab_frame - (r->length() - (nframes64_t) r->fade_out()->back()->when + r->position());
+ _pointer_frame_offset = grab_frame() - (r->length() - (nframes64_t) r->fade_out()->back()->when + r->position());
_editor->show_verbose_duration_cursor (r->last_frame() - r->fade_out()->back()->when, r->last_frame(), 10);
}
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;
tmp->audio_region()->set_fade_out_active (true);
XMLNode &after = alist->get_state();
- _editor->session->add_command(new MementoCommand<AutomationList>(*alist.get(), &before, &after));
+ _editor->session()->add_command(new MementoCommand<AutomationList>(*alist.get(), &before, &after));
}
_editor->commit_reversible_command ();
}
+void
+FadeOutDrag::aborted ()
+{
+ for (list<DraggingView>::iterator i = _views.begin(); i != _views.end(); ++i) {
+ AudioRegionView* tmp = dynamic_cast<AudioRegionView*> (i->view);
+
+ if (!tmp) {
+ continue;
+ }
+
+ tmp->reset_fade_out_shape_width (tmp->audio_region()->fade_out()->back()->when);
+ }
+}
+
MarkerDrag::MarkerDrag (Editor* e, ArdourCanvas::Item* i)
: Drag (e, i)
{
Location *location = _editor->find_location_from_marker (_marker, is_start);
_editor->_dragging_edit_point = true;
- _pointer_frame_offset = _grab_frame - (is_start ? location->start() : location->end());
+ _pointer_frame_offset = grab_frame() - (is_start ? location->start() : location->end());
update_item (location);
if (e < max_frames) {
++e;
}
- _editor->session->locations()->find_all_between (s, e, ll, Location::Flags (0));
+ _editor->session()->locations()->find_all_between (s, e, ll, Location::Flags (0));
for (Locations::LocationList::iterator i = ll.begin(); i != ll.end(); ++i) {
Editor::LocationMarkers* lm = _editor->find_location_markers (*i);
if (lm) {
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);
nframes64_t next = newframe;
- if (_current_pointer_frame == _last_pointer_frame) {
+ if (newframe == last_pointer_frame()) {
return;
}
if (copy_location->is_mark()) {
- /* just move it */
+ /* now move it */
copy_location->set_start (copy_location->start() + f_delta);
}
}
- _last_pointer_frame = _current_pointer_frame;
-
assert (!_copied_locations.empty());
_editor->show_verbose_time_cursor (newframe, 10);
_editor->_dragging_edit_point = false;
_editor->begin_reversible_command ( _("move marker") );
- XMLNode &before = _editor->session->locations()->get_state();
+ XMLNode &before = _editor->session()->locations()->get_state();
MarkerSelection::iterator i;
list<Location*>::iterator x;
}
}
- XMLNode &after = _editor->session->locations()->get_state();
- _editor->session->add_command(new MementoCommand<Locations>(*(_editor->session->locations()), &before, &after));
+ XMLNode &after = _editor->session()->locations()->get_state();
+ _editor->session()->add_command(new MementoCommand<Locations>(*(_editor->session()->locations()), &before, &after));
_editor->commit_reversible_command ();
_line->hide();
}
+void
+MarkerDrag::aborted ()
+{
+ /* XXX: TODO */
+}
+
void
MarkerDrag::update_item (Location* location)
{
// start the grab at the center of the control point so
// the point doesn't 'jump' to the mouse after the first drag
- _grab_x = _point->get_x();
- _grab_y = _point->get_y();
-
- _point->line().parent_group().i2w (_grab_x, _grab_y);
- _editor->track_canvas->w2c (_grab_x, _grab_y, _grab_x, _grab_y);
+ _time_axis_view_grab_x = _point->get_x();
+ _time_axis_view_grab_y = _point->get_y();
- _grab_frame = _editor->pixel_to_frame (_grab_x);
+ float const fraction = 1 - (_point->get_y() / _point->line().height());
- _point->line().start_drag (_point, _grab_frame, 0);
+ _point->line().start_drag_single (_point, _time_axis_view_grab_x, fraction);
- float fraction = 1.0 - (_point->get_y() / _point->line().height());
_editor->set_verbose_canvas_cursor (_point->line().get_verbose_cursor_string (fraction),
- _current_pointer_x + 10, _current_pointer_y + 10);
+ event->button.x + 10, event->button.y + 10);
_editor->show_verbose_canvas_cursor ();
}
void
ControlPointDrag::motion (GdkEvent* event, bool)
{
- double dx = _current_pointer_x - _last_pointer_x;
- double dy = _current_pointer_y - _last_pointer_y;
+ double dx = _drags->current_pointer_x() - last_pointer_x();
+ double dy = _drags->current_pointer_y() - last_pointer_y();
if (event->button.state & Keyboard::SecondaryModifier) {
dx *= 0.1;
dy *= 0.1;
}
- double cx = _grab_x + _cumulative_x_drag + dx;
- double cy = _grab_y + _cumulative_y_drag + dy;
+ /* coordinate in TimeAxisView's space */
+ double cx = _time_axis_view_grab_x + _cumulative_x_drag + dx;
+ double cy = _time_axis_view_grab_y + _cumulative_y_drag + dy;
// calculate zero crossing point. back off by .01 to stay on the
// positive side of zero
- double _unused = 0;
- double zero_gain_y = (1.0 - _zero_gain_fraction) * _point->line().height() - .01;
- _point->line().parent_group().i2w(_unused, zero_gain_y);
+ 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 and (cy - dy) > zero_gain_y)
- or (cy > zero_gain_y and (cy - dy) < zero_gain_y)) {
+ 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 = _grab_x;
+ cx = _time_axis_view_grab_x;
}
if (_y_constrained) {
- cy = _grab_y;
+ cy = _time_axis_view_grab_y;
}
- _cumulative_x_drag = cx - _grab_x;
- _cumulative_y_drag = cy - _grab_y;
-
- _point->line().parent_group().w2i (cx, cy);
+ _cumulative_x_drag = cx - _time_axis_view_grab_x;
+ _cumulative_y_drag = cy - _time_axis_view_grab_y;
cx = max (0.0, cx);
cy = max (0.0, cy);
cy = min ((double) _point->line().height(), cy);
- //translate cx to frames
nframes64_t cx_frames = _editor->unit_to_frame (cx);
if (!_x_constrained) {
bool const push = Keyboard::modifier_state_contains (event->button.state, Keyboard::PrimaryModifier);
- _point->line().point_drag (*_point, cx_frames, fraction, push);
+ _point->line().drag_motion (_editor->frame_to_unit (cx_frames), fraction, false, push);
_editor->set_verbose_canvas_cursor_text (_point->line().get_verbose_cursor_string (fraction));
}
} else {
motion (event, false);
}
- _point->line().end_drag (_point);
+ _point->line().end_drag ();
+}
+
+void
+ControlPointDrag::aborted ()
+{
+ _point->line().reset ();
}
bool
nframes64_t const frame_within_region = (nframes64_t) floor (cx * _editor->frames_per_unit);
- if (!_line->control_points_adjacent (frame_within_region, _before, _after)) {
+ uint32_t before;
+ uint32_t after;
+
+ if (!_line->control_points_adjacent (frame_within_region, before, after)) {
/* no adjacent points */
return;
}
/* store grab start in parent frame */
- _grab_x = cx;
- _grab_y = cy;
+ _time_axis_view_grab_x = cx;
+ _time_axis_view_grab_y = cy;
double fraction = 1.0 - (cy / _line->height());
- _line->start_drag (0, _grab_frame, fraction);
+ _line->start_drag_line (before, after, fraction);
_editor->set_verbose_canvas_cursor (_line->get_verbose_cursor_string (fraction),
- _current_pointer_x + 10, _current_pointer_y + 10);
+ event->button.x + 10, event->button.y + 10);
_editor->show_verbose_canvas_cursor ();
}
void
LineDrag::motion (GdkEvent* event, bool)
{
- double dy = _current_pointer_y - _last_pointer_y;
+ double dy = _drags->current_pointer_y() - last_pointer_y();
if (event->button.state & Keyboard::SecondaryModifier) {
dy *= 0.1;
}
- double cy = _grab_y + _cumulative_y_drag + dy;
+ double cy = _time_axis_view_grab_y + _cumulative_y_drag + dy;
- _cumulative_y_drag = cy - _grab_y;
+ _cumulative_y_drag = cy - _time_axis_view_grab_y;
cy = max (0.0, cy);
cy = min ((double) _line->height(), cy);
push = true;
}
- _line->line_drag (_before, _after, fraction, push);
+ /* we are ignoring x position for this drag, so we can just pass in anything */
+ _line->drag_motion (0, fraction, true, push);
_editor->set_verbose_canvas_cursor_text (_line->get_verbose_cursor_string (fraction));
}
LineDrag::finished (GdkEvent* event, bool)
{
motion (event, false);
- _line->end_drag (0);
+ _line->end_drag ();
+}
+
+void
+LineDrag::aborted ()
+{
+ _line->reset ();
}
void
RubberbandSelectDrag::start_grab (GdkEvent* event, Gdk::Cursor *)
{
Drag::start_grab (event);
- _editor->show_verbose_time_cursor (_current_pointer_frame, 10);
+ _editor->show_verbose_time_cursor (adjusted_current_frame (event), 10);
}
void
-RubberbandSelectDrag::motion (GdkEvent* event, bool first_move)
+RubberbandSelectDrag::motion (GdkEvent* event, bool)
{
nframes64_t start;
nframes64_t end;
double y1;
double y2;
- /* use a bigger drag threshold than the default */
+ nframes64_t const pf = adjusted_current_frame (event, Config->get_rubberbanding_snaps_to_grid ());
- if (abs ((int) (_current_pointer_frame - _grab_frame)) < 8) {
- return;
+ nframes64_t grab = grab_frame ();
+ if (Config->get_rubberbanding_snaps_to_grid ()) {
+ _editor->snap_to_with_modifier (grab, event);
}
- if (Config->get_rubberbanding_snaps_to_grid()) {
- if (first_move) {
- _editor->snap_to_with_modifier (_grab_frame, event);
- }
- _editor->snap_to_with_modifier (_current_pointer_frame, event);
- }
-
/* base start and end on initial click position */
- if (_current_pointer_frame < _grab_frame) {
- start = _current_pointer_frame;
- end = _grab_frame;
+ if (pf < grab) {
+ start = pf;
+ end = grab;
} else {
- end = _current_pointer_frame;
- start = _grab_frame;
+ end = pf;
+ start = grab;
}
- if (_current_pointer_y < _grab_y) {
- y1 = _current_pointer_y;
- y2 = _grab_y;
+ if (_drags->current_pointer_y() < grab_y()) {
+ y1 = _drags->current_pointer_y();
+ y2 = grab_y();
} else {
- y2 = _current_pointer_y;
- y1 = _grab_y;
+ y2 = _drags->current_pointer_y();
+ y1 = grab_y();
}
_editor->rubberband_rect->show();
_editor->rubberband_rect->raise_to_top();
- _last_pointer_frame = _current_pointer_frame;
-
- _editor->show_verbose_time_cursor (_current_pointer_frame, 10);
+ _editor->show_verbose_time_cursor (pf, 10);
}
}
motion (event, false);
double y1,y2;
- if (_current_pointer_y < _grab_y) {
- y1 = _current_pointer_y;
- y2 = _grab_y;
+ if (_drags->current_pointer_y() < grab_y()) {
+ y1 = _drags->current_pointer_y();
+ y2 = grab_y();
} else {
- y2 = _current_pointer_y;
- y1 = _grab_y;
+ y2 = _drags->current_pointer_y();
+ y1 = grab_y();
}
_editor->begin_reversible_command (_("rubberband selection"));
- if (_grab_frame < _last_pointer_frame) {
- committed = _editor->select_all_within (_grab_frame, _last_pointer_frame - 1, y1, y2, _editor->track_views, op);
+ if (grab_frame() < last_pointer_frame()) {
+ committed = _editor->select_all_within (grab_frame(), last_pointer_frame() - 1, y1, y2, _editor->track_views, op);
} else {
- committed = _editor->select_all_within (_last_pointer_frame, _grab_frame - 1, y1, y2, _editor->track_views, op);
+ committed = _editor->select_all_within (last_pointer_frame(), grab_frame() - 1, y1, y2, _editor->track_views, op);
}
if (!committed) {
_editor->rubberband_rect->hide();
}
+void
+RubberbandSelectDrag::aborted ()
+{
+ _editor->rubberband_rect->hide ();
+}
+
void
TimeFXDrag::start_grab (GdkEvent* event, Gdk::Cursor *)
{
Drag::start_grab (event);
- _editor->show_verbose_time_cursor (_current_pointer_frame, 10);
+ _editor->show_verbose_time_cursor (adjusted_current_frame (event), 10);
}
void
{
RegionView* rv = _primary;
- _editor->snap_to_with_modifier (_current_pointer_frame, event);
-
- if (_current_pointer_frame == _last_pointer_frame) {
- return;
- }
+ nframes64_t const pf = adjusted_current_frame (event);
- if (_current_pointer_frame > rv->region()->position()) {
- rv->get_time_axis_view().show_timestretch (rv->region()->position(), _current_pointer_frame);
+ if (pf > rv->region()->position()) {
+ rv->get_time_axis_view().show_timestretch (rv->region()->position(), pf);
}
- _last_pointer_frame = _current_pointer_frame;
-
- _editor->show_verbose_time_cursor (_current_pointer_frame, 10);
+ _editor->show_verbose_time_cursor (pf, 10);
}
void
return;
}
- if (_last_pointer_frame < _primary->region()->position()) {
+ if (last_pointer_frame() < _primary->region()->position()) {
/* backwards drag of the left edge - not usable */
return;
}
- nframes64_t newlen = _last_pointer_frame - _primary->region()->position();
+ nframes64_t newlen = last_pointer_frame() - _primary->region()->position();
float percentage = (double) newlen / (double) _primary->region()->length();
}
}
+void
+TimeFXDrag::aborted ()
+{
+ _primary->get_time_axis_view().hide_timestretch ();
+}
+
+
void
ScrubDrag::start_grab (GdkEvent* event, Gdk::Cursor *)
{
void
ScrubDrag::motion (GdkEvent* /*event*/, bool)
{
- _editor->scrub ();
+ _editor->scrub (adjusted_current_frame (0, false), _drags->current_pointer_x ());
}
void
ScrubDrag::finished (GdkEvent* /*event*/, bool movement_occurred)
{
- if (movement_occurred && _editor->session) {
+ if (movement_occurred && _editor->session()) {
/* make sure we stop */
- _editor->session->request_transport_speed (0.0);
+ _editor->session()->request_transport_speed (0.0);
}
}
+void
+ScrubDrag::aborted ()
+{
+ /* XXX: TODO */
+}
+
SelectionDrag::SelectionDrag (Editor* e, ArdourCanvas::Item* i, Operation o)
: Drag (e, i)
, _operation (o)
, _copy (false)
+ , _original_pointer_time_axis (-1)
+ , _last_pointer_time_axis (-1)
{
}
nframes64_t start = 0;
nframes64_t end = 0;
- if (_editor->session == 0) {
+ if (_editor->session() == 0) {
return;
}
if (_editor->clicked_axisview) {
_editor->clicked_axisview->order_selection_trims (_item, true);
}
- Drag::start_grab (event, cursor);
- cursor = _editor->trimmer_cursor;
+ Drag::start_grab (event, _editor->trimmer_cursor);
start = _editor->selection->time[_editor->clicked_selection].start;
- _pointer_frame_offset = _grab_frame - start;
+ _pointer_frame_offset = grab_frame() - start;
break;
case SelectionEndTrim:
if (_editor->clicked_axisview) {
_editor->clicked_axisview->order_selection_trims (_item, false);
}
- Drag::start_grab (event, cursor);
- cursor = _editor->trimmer_cursor;
+ Drag::start_grab (event, _editor->trimmer_cursor);
end = _editor->selection->time[_editor->clicked_selection].end;
- _pointer_frame_offset = _grab_frame - end;
+ _pointer_frame_offset = grab_frame() - end;
break;
case SelectionMove:
start = _editor->selection->time[_editor->clicked_selection].start;
Drag::start_grab (event, cursor);
- _pointer_frame_offset = _grab_frame - start;
+ _pointer_frame_offset = grab_frame() - start;
break;
}
if (_operation == SelectionMove) {
_editor->show_verbose_time_cursor (start, 10);
} else {
- _editor->show_verbose_time_cursor (_current_pointer_frame, 10);
+ _editor->show_verbose_time_cursor (adjusted_current_frame (event), 10);
}
+
+ _original_pointer_time_axis = _editor->trackview_by_y_position (_drags->current_pointer_y ()).first->order ();
}
void
nframes64_t end = 0;
nframes64_t length;
-
+ pair<TimeAxisView*, int> const pending_time_axis = _editor->trackview_by_y_position (_drags->current_pointer_y ());
+ if (pending_time_axis.first == 0) {
+ return;
+ }
+
nframes64_t const pending_position = adjusted_current_frame (event);
- /* only alter selection if the current frame is
- different from the last frame position (adjusted)
- */
+ /* only alter selection if things have changed */
- if (pending_position == _last_pointer_frame) {
+ if (pending_time_axis.first->order() == _last_pointer_time_axis && pending_position == last_pointer_frame()) {
return;
}
switch (_operation) {
case CreateSelection:
+ {
+ nframes64_t grab = grab_frame ();
if (first_move) {
- _editor->snap_to (_grab_frame);
+ _editor->snap_to (grab);
}
- if (pending_position < _grab_frame) {
+ if (pending_position < grab_frame()) {
start = pending_position;
- end = _grab_frame;
+ end = grab;
} else {
end = pending_position;
- start = _grab_frame;
+ start = grab;
}
/* first drag: Either add to the selection
- or create a new selection->
+ or create a new selection
*/
if (first_move) {
- _editor->begin_reversible_command (_("range selection"));
- _have_transaction = true;
-
if (_copy) {
/* adding to the selection */
+ _editor->selection->add (_editor->clicked_axisview);
_editor->clicked_selection = _editor->selection->add (start, end);
_copy = false;
} else {
- /* new selection-> */
- _editor->clicked_selection = _editor->selection->set (_editor->clicked_axisview, start, end);
+ /* new selection */
+
+ if (!_editor->selection->selected (_editor->clicked_axisview)) {
+ _editor->selection->set (_editor->clicked_axisview);
+ }
+
+ _editor->clicked_selection = _editor->selection->set (start, end);
}
}
- break;
-
- case SelectionStartTrim:
- if (first_move) {
- _editor->begin_reversible_command (_("trim selection start"));
- _have_transaction = true;
+ /* select the track that we're in */
+ if (find (_added_time_axes.begin(), _added_time_axes.end(), pending_time_axis.first) == _added_time_axes.end()) {
+ _editor->selection->add (pending_time_axis.first);
+ _added_time_axes.push_back (pending_time_axis.first);
}
+
+ /* deselect any tracks that this drag no longer includes, being careful to only deselect
+ tracks that we selected in the first place.
+ */
+ int min_order = min (_original_pointer_time_axis, pending_time_axis.first->order());
+ int max_order = max (_original_pointer_time_axis, pending_time_axis.first->order());
+
+ list<TimeAxisView*>::iterator i = _added_time_axes.begin();
+ while (i != _added_time_axes.end()) {
+
+ list<TimeAxisView*>::iterator tmp = i;
+ ++tmp;
+
+ if ((*i)->order() < min_order || (*i)->order() > max_order) {
+ _editor->selection->remove (*i);
+ _added_time_axes.remove (*i);
+ }
+
+ i = tmp;
+ }
+
+ }
+ break;
+
+ case SelectionStartTrim:
+
start = _editor->selection->time[_editor->clicked_selection].start;
end = _editor->selection->time[_editor->clicked_selection].end;
case SelectionEndTrim:
- if (first_move) {
- _editor->begin_reversible_command (_("trim selection end"));
- _have_transaction = true;
- }
-
start = _editor->selection->time[_editor->clicked_selection].start;
end = _editor->selection->time[_editor->clicked_selection].end;
case SelectionMove:
- if (first_move) {
- _editor->begin_reversible_command (_("move selection"));
- _have_transaction = true;
- }
-
start = _editor->selection->time[_editor->clicked_selection].start;
end = _editor->selection->time[_editor->clicked_selection].end;
_editor->selection->replace (_editor->clicked_selection, start, end);
}
- _last_pointer_frame = pending_position;
-
if (_operation == SelectionMove) {
_editor->show_verbose_time_cursor(start, 10);
} else {
void
SelectionDrag::finished (GdkEvent* event, bool movement_occurred)
{
- Session* s = _editor->session;
+ Session* s = _editor->session();
if (movement_occurred) {
motion (event, false);
_editor->selection->TimeChanged ();
}
- if (_have_transaction) {
- _editor->commit_reversible_command ();
- }
-
/* XXX what if its a music time selection? */
if (s && (s->config.get_auto_play() || (s->get_play_range() && s->transport_rolling()))) {
s->request_play_range (&_editor->selection->time, true);
/* just a click, no pointer movement.*/
if (Keyboard::no_modifier_keys_pressed (&event->button)) {
-
_editor->selection->clear_time();
+ }
+ if (!_editor->selection->selected (_editor->clicked_axisview)) {
+ _editor->selection->set (_editor->clicked_axisview);
}
if (s && s->get_play_range () && s->transport_rolling()) {
_editor->stop_canvas_autoscroll ();
}
+void
+SelectionDrag::aborted ()
+{
+ /* XXX: TODO */
+}
+
RangeMarkerBarDrag::RangeMarkerBarDrag (Editor* e, ArdourCanvas::Item* i, Operation o)
: Drag (e, i),
_operation (o),
void
RangeMarkerBarDrag::start_grab (GdkEvent* event, Gdk::Cursor *)
{
- if (_editor->session == 0) {
+ if (_editor->session() == 0) {
return;
}
Drag::start_grab (event, cursor);
- _editor->show_verbose_time_cursor (_current_pointer_frame, 10);
+ _editor->show_verbose_time_cursor (adjusted_current_frame (event), 10);
}
void
break;
}
- _editor->snap_to_with_modifier (_current_pointer_frame, event);
+ nframes64_t const pf = adjusted_current_frame (event);
- /* only alter selection if the current frame is
- different from the last frame position.
- */
-
- if (_current_pointer_frame == _last_pointer_frame) {
- return;
- }
-
- switch (_operation) {
- case CreateRangeMarker:
- case CreateTransportMarker:
- case CreateCDMarker:
- if (first_move) {
- _editor->snap_to (_grab_frame);
- }
-
- if (_current_pointer_frame < _grab_frame) {
- start = _current_pointer_frame;
- end = _grab_frame;
+ if (_operation == CreateRangeMarker || _operation == CreateTransportMarker || _operation == CreateCDMarker) {
+ nframes64_t grab = grab_frame ();
+ _editor->snap_to (grab);
+
+ if (pf < grab_frame()) {
+ start = pf;
+ end = grab;
} else {
- end = _current_pointer_frame;
- start = _grab_frame;
+ end = pf;
+ start = grab;
}
/* first drag: Either add to the selection
//_drag_rect->raise_to_top();
}
- break;
}
if (event->button.x >= _editor->horizontal_adjustment.get_value() + _editor->_canvas_width) {
update_item (_editor->temp_location);
}
- _last_pointer_frame = _current_pointer_frame;
-
- _editor->show_verbose_time_cursor (_current_pointer_frame, 10);
+ _editor->show_verbose_time_cursor (pf, 10);
}
case CreateCDMarker:
{
_editor->begin_reversible_command (_("new range marker"));
- XMLNode &before = _editor->session->locations()->get_state();
- _editor->session->locations()->next_available_name(rangename,"unnamed");
+ XMLNode &before = _editor->session()->locations()->get_state();
+ _editor->session()->locations()->next_available_name(rangename,"unnamed");
if (_operation == CreateCDMarker) {
flags = Location::IsRangeMarker | Location::IsCDMarker;
_editor->cd_marker_bar_drag_rect->hide();
_editor->range_bar_drag_rect->hide();
}
newloc = new Location(_editor->temp_location->start(), _editor->temp_location->end(), rangename, (Location::Flags) flags);
- _editor->session->locations()->add (newloc, true);
- XMLNode &after = _editor->session->locations()->get_state();
- _editor->session->add_command(new MementoCommand<Locations>(*(_editor->session->locations()), &before, &after));
+ _editor->session()->locations()->add (newloc, true);
+ XMLNode &after = _editor->session()->locations()->get_state();
+ _editor->session()->add_command(new MementoCommand<Locations>(*(_editor->session()->locations()), &before, &after));
_editor->commit_reversible_command ();
break;
}
nframes64_t start;
nframes64_t end;
- _editor->session->locations()->marks_either_side (_grab_frame, start, end);
+ _editor->session()->locations()->marks_either_side (grab_frame(), start, end);
if (end == max_frames) {
- end = _editor->session->current_end_frame ();
+ end = _editor->session()->current_end_frame ();
}
if (start == max_frames) {
- start = _editor->session->current_start_frame ();
+ start = _editor->session()->current_start_frame ();
}
switch (_editor->mouse_mode) {
case MouseRange:
/* find the two markers on either side of the click and make the range out of it */
- _editor->selection->set (0, start, end);
+ _editor->selection->set (start, end);
break;
default:
_editor->stop_canvas_autoscroll ();
}
-
+void
+RangeMarkerBarDrag::aborted ()
+{
+ /* XXX: TODO */
+}
void
RangeMarkerBarDrag::update_item (Location* location)
MouseZoomDrag::start_grab (GdkEvent* event, Gdk::Cursor *)
{
Drag::start_grab (event, _editor->zoom_cursor);
- _editor->show_verbose_time_cursor (_current_pointer_frame, 10);
+ _editor->show_verbose_time_cursor (adjusted_current_frame (event), 10);
}
void
nframes64_t start;
nframes64_t end;
- _editor->snap_to_with_modifier (_current_pointer_frame, event);
+ nframes64_t const pf = adjusted_current_frame (event);
- if (first_move) {
- _editor->snap_to_with_modifier (_grab_frame, event);
- }
-
- if (_current_pointer_frame == _last_pointer_frame) {
- return;
- }
+ nframes64_t grab = grab_frame ();
+ _editor->snap_to_with_modifier (grab, event);
/* base start and end on initial click position */
- if (_current_pointer_frame < _grab_frame) {
- start = _current_pointer_frame;
- end = _grab_frame;
+ if (pf < grab) {
+ start = pf;
+ end = grab;
} else {
- end = _current_pointer_frame;
- start = _grab_frame;
+ end = pf;
+ start = grab;
}
if (start != end) {
_editor->reposition_zoom_rect(start, end);
- _last_pointer_frame = _current_pointer_frame;
-
- _editor->show_verbose_time_cursor (_current_pointer_frame, 10);
+ _editor->show_verbose_time_cursor (pf, 10);
}
}
if (movement_occurred) {
motion (event, false);
- if (_grab_frame < _last_pointer_frame) {
- _editor->temporal_zoom_by_frame (_grab_frame, _last_pointer_frame, "mouse zoom");
+ if (grab_frame() < last_pointer_frame()) {
+ _editor->temporal_zoom_by_frame (grab_frame(), last_pointer_frame(), "mouse zoom");
} else {
- _editor->temporal_zoom_by_frame (_last_pointer_frame, _grab_frame, "mouse zoom");
+ _editor->temporal_zoom_by_frame (last_pointer_frame(), grab_frame(), "mouse zoom");
}
} else {
- _editor->temporal_zoom_to_frame (false, _grab_frame);
+ _editor->temporal_zoom_to_frame (false, grab_frame());
/*
temporal_zoom_step (false);
- center_screen (_grab_frame);
+ center_screen (grab_frame());
*/
}
_editor->zoom_rect->hide();
}
+void
+MouseZoomDrag::aborted ()
+{
+ _editor->zoom_rect->hide ();
+}
+
NoteDrag::NoteDrag (Editor* e, ArdourCanvas::Item* i)
: Drag (e, i)
{
double event_x;
double event_y;
- event_x = _current_pointer_x;
- event_y = _current_pointer_y;
+ event_x = _drags->current_pointer_x();
+ event_y = _drags->current_pointer_y();
_item->property_parent().get_value()->w2i(event_x, event_y);
double event_x;
double event_y;
- event_x = _current_pointer_x;
- event_y = _current_pointer_y;
+ event_x = _drags->current_pointer_x();
+ event_y = _drags->current_pointer_y();
_item->property_parent().get_value()->w2i(event_x, event_y);
region->note_dropped (cnote, drag_delta_x, drag_delta_note);
}
}
+
+void
+NoteDrag::aborted ()
+{
+ /* XXX: TODO */
+}
+
+AutomationRangeDrag::AutomationRangeDrag (Editor* e, ArdourCanvas::Item* i, list<AudioRange> const & r)
+ : Drag (e, i)
+ , _ranges (r)
+ , _nothing_to_drag (false)
+{
+ _atav = reinterpret_cast<AutomationTimeAxisView*> (_item->get_data ("trackview"));
+ assert (_atav);
+
+ _line = _atav->line ();
+}
+
+void
+AutomationRangeDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor)
+{
+ Drag::start_grab (event, cursor);
+
+ list<ControlPoint*> points;
+
+ XMLNode* state = &_line->get_state ();
+
+ if (_ranges.empty()) {
+
+ uint32_t const N = _line->npoints ();
+ for (uint32_t i = 0; i < N; ++i) {
+ points.push_back (_line->nth (i));
+ }
+
+ } else {
+
+ boost::shared_ptr<AutomationList> the_list = _line->the_list ();
+ for (list<AudioRange>::const_iterator j = _ranges.begin(); j != _ranges.end(); ++j) {
+
+ /* fade into and out of the region that we're dragging;
+ 64 samples length plucked out of thin air.
+ */
+ nframes64_t const h = (j->start + j->end) / 2;
+ nframes64_t a = j->start + 64;
+ if (a > h) {
+ a = h;
+ }
+ nframes64_t b = j->end - 64;
+ if (b < h) {
+ b = h;
+ }
+
+ the_list->add (j->start, the_list->eval (j->start));
+ _line->add_always_in_view (j->start);
+ the_list->add (a, the_list->eval (a));
+ _line->add_always_in_view (a);
+ the_list->add (b, the_list->eval (b));
+ _line->add_always_in_view (b);
+ the_list->add (j->end, the_list->eval (j->end));
+ _line->add_always_in_view (j->end);
+ }
+
+ uint32_t const N = _line->npoints ();
+ for (uint32_t i = 0; i < N; ++i) {
+
+ ControlPoint* p = _line->nth (i);
+
+ list<AudioRange>::const_iterator j = _ranges.begin ();
+ while (j != _ranges.end() && (j->start >= (*p->model())->when || j->end <= (*p->model())->when)) {
+ ++j;
+ }
+
+ if (j != _ranges.end()) {
+ points.push_back (p);
+ }
+ }
+ }
+
+ if (points.empty()) {
+ _nothing_to_drag = true;
+ return;
+ }
+
+ _line->start_drag_multiple (points, 1 - (_drags->current_pointer_y() / _line->height ()), state);
+}
+
+void
+AutomationRangeDrag::motion (GdkEvent* event, bool first_move)
+{
+ if (_nothing_to_drag) {
+ return;
+ }
+
+ float const f = 1 - (_drags->current_pointer_y() / _line->height());
+
+ /* we are ignoring x position for this drag, so we can just pass in anything */
+ _line->drag_motion (0, f, true, false);
+}
+
+void
+AutomationRangeDrag::finished (GdkEvent* event, bool)
+{
+ if (_nothing_to_drag) {
+ return;
+ }
+
+ motion (event, false);
+ _line->end_drag ();
+ _line->clear_always_in_view ();
+}
+
+void
+AutomationRangeDrag::aborted ()
+{
+ _line->clear_always_in_view ();
+ _line->reset ();
+}
+
+DraggingView::DraggingView (RegionView* v)
+ : view (v)
+{
+ initial_y = v->get_canvas_group()->property_y ();
+}