Allow multiple simulataneous Drags to be active, and hence set up and drag time ranges when moving regions in PT-edit mode.

git-svn-id: svn://localhost/ardour2/branches/3.0@6478 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Carl Hetherington 2010-01-12 16:14:49 +00:00
parent 642f41b82f
commit 11bd4eed89
14 changed files with 414 additions and 350 deletions

View file

@ -281,7 +281,7 @@ Editor::Editor ()
clicked_crossfadeview = 0; clicked_crossfadeview = 0;
clicked_control_point = 0; clicked_control_point = 0;
last_update_frame = 0; last_update_frame = 0;
_drag = 0; _drags = new DragManager (this);
current_mixer_strip = 0; current_mixer_strip = 0;
current_bbt_points = 0; current_bbt_points = 0;
tempo_lines = 0; tempo_lines = 0;
@ -714,7 +714,7 @@ Editor::~Editor()
delete _routes; delete _routes;
delete _route_groups; delete _route_groups;
delete track_canvas; delete track_canvas;
delete _drag; delete _drags;
} }
void void
@ -731,10 +731,8 @@ Editor::catch_vanishing_regionview (RegionView *rv)
audioregionview by itself. audioregionview by itself.
*/ */
if (_drag && rv->get_canvas_group() == _drag->item() && !_drag->ending()) { if (_drags->active() && _drags->have_item (rv->get_canvas_group()) && !_drags->ending()) {
_drag->end_grab (0); _drags->abort ();
delete _drag;
_drag = 0;
} }
if (clicked_regionview == rv) { if (clicked_regionview == rv) {

View file

@ -107,7 +107,7 @@ class AutomationTimeAxisView;
class BundleManager; class BundleManager;
class ControlPoint; class ControlPoint;
class CrossfadeView; class CrossfadeView;
class Drag; class DragManager;
class GlobalPortMatrixWindow; class GlobalPortMatrixWindow;
class GroupedButtons; class GroupedButtons;
class Marker; class Marker;
@ -607,7 +607,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
void collect_new_region_view (RegionView *); void collect_new_region_view (RegionView *);
void collect_and_select_new_region_view (RegionView *); void collect_and_select_new_region_view (RegionView *);
void select_range_around_region (RegionView *); long select_range_around_region (RegionView *);
Gtk::Menu track_context_menu; Gtk::Menu track_context_menu;
Gtk::Menu track_region_context_menu; Gtk::Menu track_region_context_menu;
@ -1260,7 +1260,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
int scrubbing_direction; int scrubbing_direction;
int scrub_reversals; int scrub_reversals;
int scrub_reverse_distance; int scrub_reverse_distance;
void scrub (); void scrub (nframes64_t, double);
void keyboard_selection_begin (); void keyboard_selection_begin ();
void keyboard_selection_finish (bool add); void keyboard_selection_finish (bool add);
@ -1279,9 +1279,8 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
bool ignore_gui_changes; bool ignore_gui_changes;
Drag* _drag; DragManager* _drags;
void break_drag ();
void escape (); void escape ();
Gtk::Menu fade_context_menu; Gtk::Menu fade_context_menu;
@ -1305,10 +1304,10 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
gint mouse_rename_region (ArdourCanvas::Item*, GdkEvent*); gint mouse_rename_region (ArdourCanvas::Item*, GdkEvent*);
void start_region_grab (ArdourCanvas::Item*, GdkEvent*, RegionView*); void add_region_drag (ArdourCanvas::Item*, GdkEvent*, RegionView*);
void start_create_region_grab (ArdourCanvas::Item*, GdkEvent*); void start_create_region_grab (ArdourCanvas::Item*, GdkEvent*);
void start_region_copy_grab (ArdourCanvas::Item*, GdkEvent*, RegionView*); void add_region_copy_drag (ArdourCanvas::Item*, GdkEvent*, RegionView*);
void start_region_brush_grab (ArdourCanvas::Item*, GdkEvent*, RegionView*); void add_region_brush_drag (ArdourCanvas::Item*, GdkEvent*, RegionView*);
void start_selection_grab (ArdourCanvas::Item*, GdkEvent*); void start_selection_grab (ArdourCanvas::Item*, GdkEvent*);
void region_view_item_click (AudioRegionView&, GdkEventButton*); void region_view_item_click (AudioRegionView&, GdkEventButton*);
@ -1676,7 +1675,7 @@ public:
bool allow_vertical_scroll; bool allow_vertical_scroll;
/* trimming */ /* trimming */
void point_trim (GdkEvent*); void point_trim (GdkEvent *, nframes64_t);
void single_contents_trim (RegionView&, nframes64_t, bool, bool, bool); void single_contents_trim (RegionView&, nframes64_t, bool, bool, bool);
void single_start_trim (RegionView&, nframes64_t, bool, bool, bool); void single_start_trim (RegionView&, nframes64_t, bool, bool, bool);
void single_end_trim (RegionView&, nframes64_t, bool, bool, bool); void single_end_trim (RegionView&, nframes64_t, bool, bool, bool);

View file

@ -541,17 +541,14 @@ Editor::drop_regions (const RefPtr<Gdk::DragContext>& /*context*/,
const SelectionData& /*data*/, const SelectionData& /*data*/,
guint /*info*/, guint /*time*/) guint /*info*/, guint /*time*/)
{ {
assert (_drag); _drags->end_grab (0);
_drag->end_grab (0);
delete _drag;
_drag = 0;
} }
void void
Editor::maybe_autoscroll (GdkEventMotion* event, bool allow_vert) Editor::maybe_autoscroll (GdkEventMotion* event, bool allow_vert)
{ {
nframes64_t rightmost_frame = leftmost_frame + current_page_frames(); nframes64_t rightmost_frame = leftmost_frame + current_page_frames();
pair<nframes64_t, nframes64_t> frames = _drag->extent (); pair<nframes64_t, nframes64_t> frames = _drags->extent ();
bool startit = false; bool startit = false;
autoscroll_y = 0; autoscroll_y = 0;
@ -610,11 +607,9 @@ Editor::autoscroll_canvas ()
double new_pixel; double new_pixel;
double target_pixel; double target_pixel;
assert (_drag);
if (autoscroll_x_distance != 0) { if (autoscroll_x_distance != 0) {
pair<nframes64_t, nframes64_t> const e = _drag->extent (); pair<nframes64_t, nframes64_t> const e = _drags->extent ();
if (autoscroll_x > 0) { if (autoscroll_x > 0) {
autoscroll_x_distance = (e.second - (leftmost_frame + current_page_frames())) / 3; autoscroll_x_distance = (e.second - (leftmost_frame + current_page_frames())) / 3;
@ -626,10 +621,10 @@ Editor::autoscroll_canvas ()
if (autoscroll_y_distance != 0) { if (autoscroll_y_distance != 0) {
if (autoscroll_y > 0) { if (autoscroll_y > 0) {
autoscroll_y_distance = (_drag->current_pointer_y() - (get_trackview_group_vertical_offset() + _canvas_height)) / 3; autoscroll_y_distance = (_drags->current_pointer_y() - (get_trackview_group_vertical_offset() + _canvas_height)) / 3;
} else if (autoscroll_y < 0) { } else if (autoscroll_y < 0) {
autoscroll_y_distance = (vertical_adjustment.get_value () - _drag->current_pointer_y()) / 3; autoscroll_y_distance = (vertical_adjustment.get_value () - _drags->current_pointer_y()) / 3;
} }
} }
@ -659,7 +654,7 @@ Editor::autoscroll_canvas ()
new_pixel = vertical_pos - autoscroll_y_distance; new_pixel = vertical_pos - autoscroll_y_distance;
} }
target_pixel = _drag->current_pointer_y() - autoscroll_y_distance; target_pixel = _drags->current_pointer_y() - autoscroll_y_distance;
target_pixel = max (target_pixel, 0.0); target_pixel = max (target_pixel, 0.0);
} else if (autoscroll_y > 0) { } else if (autoscroll_y > 0) {
@ -674,7 +669,7 @@ Editor::autoscroll_canvas ()
new_pixel = min (top_of_bottom_of_canvas, new_pixel); new_pixel = min (top_of_bottom_of_canvas, new_pixel);
target_pixel = _drag->current_pointer_y() + autoscroll_y_distance; target_pixel = _drags->current_pointer_y() + autoscroll_y_distance;
/* don't move to the full canvas height because the item will be invisible /* don't move to the full canvas height because the item will be invisible
(its top edge will line up with the bottom of the visible canvas. (its top edge will line up with the bottom of the visible canvas.
@ -683,7 +678,7 @@ Editor::autoscroll_canvas ()
target_pixel = min (target_pixel, full_canvas_height - 10); target_pixel = min (target_pixel, full_canvas_height - 10);
} else { } else {
target_pixel = _drag->current_pointer_y(); target_pixel = _drags->current_pointer_y();
new_pixel = vertical_pos; new_pixel = vertical_pos;
} }
@ -709,7 +704,7 @@ Editor::autoscroll_canvas ()
ev.x = x; ev.x = x;
ev.y = y; ev.y = y;
motion_handler (_drag->item(), (GdkEvent*) &ev, true); motion_handler (0, (GdkEvent*) &ev, true);
autoscroll_cnt++; autoscroll_cnt++;

View file

@ -196,10 +196,8 @@ Editor::track_canvas_button_press_event (GdkEventButton */*event*/)
bool bool
Editor::track_canvas_button_release_event (GdkEventButton *event) Editor::track_canvas_button_release_event (GdkEventButton *event)
{ {
if (_drag) { if (_drags->active ()) {
_drag->end_grab ((GdkEvent*) event); _drags->end_grab ((GdkEvent*) event);
delete _drag;
_drag = 0;
} }
return false; return false;
} }
@ -1008,7 +1006,7 @@ Editor::track_canvas_drag_motion (Glib::RefPtr<Gdk::DragContext> const & /*c*/,
/* assume we're dragging with button 1 */ /* assume we're dragging with button 1 */
event.motion.state = Gdk::BUTTON1_MASK; event.motion.state = Gdk::BUTTON1_MASK;
if (_drag == 0) { if (!_drags->active ()) {
double px; double px;
double py; double py;
@ -1042,11 +1040,10 @@ Editor::track_canvas_drag_motion (Glib::RefPtr<Gdk::DragContext> const & /*c*/,
return true; return true;
} }
_drag = new RegionInsertDrag (this, region_copy, rtav, pos); _drags->set (new RegionInsertDrag (this, region_copy, rtav, pos), &event);
_drag->start_grab (&event);
} }
_drag->motion_handler (&event, false); _drags->motion_handler (&event, false);
return true; return true;
} }

View file

@ -53,15 +53,149 @@ using Gtkmm2ext::Keyboard;
double const ControlPointDrag::_zero_gain_fraction = gain_to_slider_position (dB_to_coefficient (0.0)); 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 ();
}
pair<nframes64_t, nframes64_t>
DragManager::extent () const
{
if (_drags.empty()) {
return make_pair (0, 0);
}
list<Drag*>::const_iterator i = _drags.begin ();
pair<nframes64_t, nframes64_t> e = (*i)->extent ();
++i;
while (i != _drags.end()) {
pair<nframes64_t, nframes64_t> const t = (*i)->extent ();
e.first = min (e.first, t.first);
e.second = max (e.second, t.second);
++i;
}
return e;
}
Drag::Drag (Editor* e, ArdourCanvas::Item* i) Drag::Drag (Editor* e, ArdourCanvas::Item* i)
: _editor (e) : _editor (e)
, _item (i) , _item (i)
, _pointer_frame_offset (0) , _pointer_frame_offset (0)
, _ending (false)
, _move_threshold_passed (false) , _move_threshold_passed (false)
, _grab_frame (0) , _grab_frame (0)
, _last_pointer_frame (0) , _last_pointer_frame (0)
, _current_pointer_frame (0)
{ {
} }
@ -104,11 +238,8 @@ Drag::start_grab (GdkEvent* event, Gdk::Cursor *cursor)
_grab_frame = _editor->event_frame (event, &_grab_x, &_grab_y); _grab_frame = _editor->event_frame (event, &_grab_x, &_grab_y);
_grab_frame = adjusted_frame (_grab_frame, event); _grab_frame = adjusted_frame (_grab_frame, event);
_last_pointer_frame = _grab_frame; _last_pointer_frame = _grab_frame;
_current_pointer_frame = _grab_frame; _last_pointer_x = _grab_x;
_current_pointer_x = _grab_x; _last_pointer_y = _grab_y;
_current_pointer_y = _grab_y;
_last_pointer_x = _current_pointer_x;
_last_pointer_y = _current_pointer_y;
_item->grab (Gdk::POINTER_MOTION_MASK|Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK, _item->grab (Gdk::POINTER_MOTION_MASK|Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK,
*cursor, *cursor,
@ -138,20 +269,14 @@ Drag::start_grab (GdkEvent* event, Gdk::Cursor *cursor)
bool bool
Drag::end_grab (GdkEvent* event) Drag::end_grab (GdkEvent* event)
{ {
_ending = true;
_editor->stop_canvas_autoscroll (); _editor->stop_canvas_autoscroll ();
_item->ungrab (event ? event->button.time : 0); _item->ungrab (event ? event->button.time : 0);
_last_pointer_x = _current_pointer_x;
_last_pointer_y = _current_pointer_y;
finished (event, _move_threshold_passed); finished (event, _move_threshold_passed);
_editor->hide_verbose_canvas_cursor(); _editor->hide_verbose_canvas_cursor();
_ending = false;
return _move_threshold_passed; return _move_threshold_passed;
} }
@ -174,17 +299,15 @@ Drag::adjusted_frame (nframes64_t f, GdkEvent const * event, bool snap) const
nframes64_t nframes64_t
Drag::adjusted_current_frame (GdkEvent const * event, bool snap) const Drag::adjusted_current_frame (GdkEvent const * event, bool snap) const
{ {
return adjusted_frame (_current_pointer_frame, event, snap); return adjusted_frame (_drags->current_pointer_frame (), event, snap);
} }
bool bool
Drag::motion_handler (GdkEvent* event, bool from_autoscroll) Drag::motion_handler (GdkEvent* event, bool from_autoscroll)
{ {
_current_pointer_frame = _editor->event_frame (event, &_current_pointer_x, &_current_pointer_y);
/* check to see if we have moved in any way that matters since the last motion event */ /* 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)) && if ( (!x_movement_matters() || _last_pointer_frame == adjusted_current_frame (event)) &&
(!y_movement_matters() || _last_pointer_y == _current_pointer_y) ) { (!y_movement_matters() || _last_pointer_y == _drags->current_pointer_y ()) ) {
return false; return false;
} }
@ -195,7 +318,7 @@ Drag::motion_handler (GdkEvent* event, bool from_autoscroll)
if (!from_autoscroll && !_move_threshold_passed) { if (!from_autoscroll && !_move_threshold_passed) {
bool const xp = (::llabs (adjusted_current_frame (event) - _grab_frame) >= threshold.first); bool const xp = (::llabs (adjusted_current_frame (event) - _grab_frame) >= threshold.first);
bool const yp = (::fabs ((_current_pointer_y - _grab_y)) >= threshold.second); bool const yp = (::fabs ((_drags->current_pointer_y () - _grab_y)) >= threshold.second);
_move_threshold_passed = ((xp && x_movement_matters()) || (yp && y_movement_matters())); _move_threshold_passed = ((xp && x_movement_matters()) || (yp && y_movement_matters()));
} }
@ -209,8 +332,8 @@ Drag::motion_handler (GdkEvent* event, bool from_autoscroll)
motion (event, _move_threshold_passed != old_move_threshold_passed); motion (event, _move_threshold_passed != old_move_threshold_passed);
_last_pointer_x = _current_pointer_x; _last_pointer_x = _drags->current_pointer_x ();
_last_pointer_y = _current_pointer_y; _last_pointer_y = _drags->current_pointer_y ();
_last_pointer_frame = adjusted_current_frame (event); _last_pointer_frame = adjusted_current_frame (event);
return true; return true;
@ -223,8 +346,6 @@ Drag::motion_handler (GdkEvent* event, bool from_autoscroll)
void void
Drag::break_drag () Drag::break_drag ()
{ {
_ending = true;
if (_item) { if (_item) {
_item->ungrab (0); _item->ungrab (0);
} }
@ -233,8 +354,6 @@ Drag::break_drag ()
_editor->stop_canvas_autoscroll (); _editor->stop_canvas_autoscroll ();
_editor->hide_verbose_canvas_cursor (); _editor->hide_verbose_canvas_cursor ();
_ending = false;
} }
pair<nframes64_t, nframes64_t> pair<nframes64_t, nframes64_t>
@ -255,7 +374,7 @@ RegionDrag::RegionDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list<Re
void void
RegionDrag::region_going_away (RegionView* v) RegionDrag::region_going_away (RegionView* v)
{ {
if (!ending ()) { if (!_drags->ending ()) {
_views.remove (v); _views.remove (v);
} }
} }
@ -1102,7 +1221,7 @@ RegionMotionDrag::check_possible (RouteTimeAxisView** tv, layer_t* layer)
{ {
/* Which trackview is this ? */ /* 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); (*tv) = dynamic_cast<RouteTimeAxisView*> (tvp.first);
(*layer) = tvp.second; (*layer) = tvp.second;
@ -1335,7 +1454,7 @@ RegionSpliceDrag::motion (GdkEvent* event, bool)
int dir; int dir;
if ((current_pointer_x() - last_pointer_x()) > 0) { if ((_drags->current_pointer_x() - last_pointer_x()) > 0) {
dir = 1; dir = 1;
} else { } else {
dir = -1; dir = -1;
@ -1501,7 +1620,7 @@ NoteResizeDrag::motion (GdkEvent* /*event*/, bool /*first_move*/)
{ {
MidiRegionSelection& ms (_editor->get_selection().midi_regions); MidiRegionSelection& ms (_editor->get_selection().midi_regions);
for (MidiRegionSelection::iterator r = ms.begin(); r != ms.end(); ++r) { 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);
} }
} }
@ -1510,7 +1629,7 @@ NoteResizeDrag::finished (GdkEvent*, bool /*movement_occurred*/)
{ {
MidiRegionSelection& ms (_editor->get_selection().midi_regions); MidiRegionSelection& ms (_editor->get_selection().midi_regions);
for (MidiRegionSelection::iterator r = ms.begin(); r != ms.end(); ++r) { 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);
} }
} }
@ -1754,7 +1873,7 @@ TrimDrag::finished (GdkEvent* event, bool movement_occurred)
} else { } else {
/* no mouse movement */ /* no mouse movement */
_editor->point_trim (event); _editor->point_trim (event, adjusted_current_frame (event));
} }
} }
@ -2614,8 +2733,8 @@ ControlPointDrag::start_grab (GdkEvent* event, Gdk::Cursor* /*cursor*/)
void void
ControlPointDrag::motion (GdkEvent* event, bool) ControlPointDrag::motion (GdkEvent* event, bool)
{ {
double dx = current_pointer_x() - last_pointer_x(); double dx = _drags->current_pointer_x() - last_pointer_x();
double dy = current_pointer_y() - last_pointer_y(); double dy = _drags->current_pointer_y() - last_pointer_y();
if (event->button.state & Keyboard::SecondaryModifier) { if (event->button.state & Keyboard::SecondaryModifier) {
dx *= 0.1; dx *= 0.1;
@ -2753,7 +2872,7 @@ LineDrag::start_grab (GdkEvent* event, Gdk::Cursor* /*cursor*/)
void void
LineDrag::motion (GdkEvent* event, bool) 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) { if (event->button.state & Keyboard::SecondaryModifier) {
dy *= 0.1; dy *= 0.1;
@ -2827,11 +2946,11 @@ RubberbandSelectDrag::motion (GdkEvent* event, bool)
start = grab; start = grab;
} }
if (current_pointer_y() < grab_y()) { if (_drags->current_pointer_y() < grab_y()) {
y1 = current_pointer_y(); y1 = _drags->current_pointer_y();
y2 = grab_y(); y2 = grab_y();
} else { } else {
y2 = current_pointer_y(); y2 = _drags->current_pointer_y();
y1 = grab_y(); y1 = grab_y();
} }
@ -2861,11 +2980,11 @@ RubberbandSelectDrag::finished (GdkEvent* event, bool movement_occurred)
motion (event, false); motion (event, false);
double y1,y2; double y1,y2;
if (current_pointer_y() < grab_y()) { if (_drags->current_pointer_y() < grab_y()) {
y1 = current_pointer_y(); y1 = _drags->current_pointer_y();
y2 = grab_y(); y2 = grab_y();
} else { } else {
y2 = current_pointer_y(); y2 = _drags->current_pointer_y();
y1 = grab_y(); y1 = grab_y();
} }
@ -2978,7 +3097,7 @@ ScrubDrag::start_grab (GdkEvent* event, Gdk::Cursor *)
void void
ScrubDrag::motion (GdkEvent* /*event*/, bool) ScrubDrag::motion (GdkEvent* /*event*/, bool)
{ {
_editor->scrub (); _editor->scrub (adjusted_current_frame (0, false), _drags->current_pointer_x ());
} }
void void
@ -3060,7 +3179,7 @@ SelectionDrag::start_grab (GdkEvent* event, Gdk::Cursor*)
_editor->show_verbose_time_cursor (adjusted_current_frame (event), 10); _editor->show_verbose_time_cursor (adjusted_current_frame (event), 10);
} }
_original_pointer_time_axis = _editor->trackview_by_y_position (current_pointer_y ()).first->order (); _original_pointer_time_axis = _editor->trackview_by_y_position (_drags->current_pointer_y ()).first->order ();
} }
void void
@ -3070,7 +3189,7 @@ SelectionDrag::motion (GdkEvent* event, bool first_move)
nframes64_t end = 0; nframes64_t end = 0;
nframes64_t length; nframes64_t length;
pair<TimeAxisView*, int> const pending_time_axis = _editor->trackview_by_y_position (current_pointer_y ()); pair<TimeAxisView*, int> const pending_time_axis = _editor->trackview_by_y_position (_drags->current_pointer_y ());
if (pending_time_axis.first == 0) { if (pending_time_axis.first == 0) {
return; return;
} }
@ -3547,8 +3666,8 @@ NoteDrag::start_grab (GdkEvent* event, Gdk::Cursor *)
double event_x; double event_x;
double event_y; double event_y;
event_x = current_pointer_x(); event_x = _drags->current_pointer_x();
event_y = current_pointer_y(); event_y = _drags->current_pointer_y();
_item->property_parent().get_value()->w2i(event_x, event_y); _item->property_parent().get_value()->w2i(event_x, event_y);
@ -3585,8 +3704,8 @@ NoteDrag::motion (GdkEvent*, bool)
double event_x; double event_x;
double event_y; double event_y;
event_x = current_pointer_x(); event_x = _drags->current_pointer_x();
event_y = current_pointer_y(); event_y = _drags->current_pointer_y();
_item->property_parent().get_value()->w2i(event_x, event_y); _item->property_parent().get_value()->w2i(event_x, event_y);
@ -3738,7 +3857,7 @@ AutomationRangeDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor)
return; return;
} }
_line->start_drag_multiple (points, 1 - (current_pointer_y() / _line->height ()), state); _line->start_drag_multiple (points, 1 - (_drags->current_pointer_y() / _line->height ()), state);
} }
void void
@ -3748,7 +3867,7 @@ AutomationRangeDrag::motion (GdkEvent* event, bool first_move)
return; return;
} }
float const f = 1 - (current_pointer_y() / _line->height()); 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 */ /* we are ignoring x position for this drag, so we can just pass in anything */
_line->drag_motion (0, f, true, false); _line->drag_motion (0, f, true, false);

View file

@ -37,29 +37,36 @@ namespace ARDOUR {
class Editor; class Editor;
class EditorCursor; class EditorCursor;
class TimeAxisView; class TimeAxisView;
class Drag;
/** Abstract base class for dragging of things within the editor */ /** Class to manage current drags */
class Drag class DragManager
{ {
public: public:
Drag (Editor *, ArdourCanvas::Item *);
virtual ~Drag () {}
/** @return the canvas item being dragged */ DragManager (Editor* e);
ArdourCanvas::Item* item () const { ~DragManager ();
return _item;
}
void swap_grab (ArdourCanvas::Item *, Gdk::Cursor *, uint32_t); bool motion_handler (GdkEvent *, bool);
bool motion_handler (GdkEvent*, bool);
void abort ();
void break_drag (); void break_drag ();
void add (Drag *);
void set (Drag *, GdkEvent *, Gdk::Cursor* c = 0);
void start_grab (GdkEvent *);
bool end_grab (GdkEvent *);
bool have_item (ArdourCanvas::Item *) const;
std::pair<nframes64_t, nframes64_t> extent () const;
/** @return true if an end drag is in progress */ /** @return true if an end drag or break_drag is in progress */
bool ending () const { bool ending () const {
return _ending; return _ending;
} }
bool active () const {
return !_drags.empty ();
}
/** @return current pointer x position in trackview coordinates */ /** @return current pointer x position in trackview coordinates */
double current_pointer_x () const { double current_pointer_x () const {
return _current_pointer_x; return _current_pointer_x;
@ -70,6 +77,40 @@ public:
return _current_pointer_y; return _current_pointer_y;
} }
/** @return current pointer frame */
nframes64_t current_pointer_frame () const {
return _current_pointer_frame;
}
private:
Editor* _editor;
std::list<Drag*> _drags;
bool _ending; ///< true if end_grab or break_drag is in progress, otherwise false
double _current_pointer_x; ///< trackview x of the current pointer
double _current_pointer_y; ///< trackview y of the current pointer
nframes64_t _current_pointer_frame; ///< frame that the pointer is now at
};
/** Abstract base class for dragging of things within the editor */
class Drag
{
public:
Drag (Editor *, ArdourCanvas::Item *);
virtual ~Drag () {}
void set_manager (DragManager* m) {
_drags = m;
}
/** @return the canvas item being dragged */
ArdourCanvas::Item* item () const {
return _item;
}
void swap_grab (ArdourCanvas::Item *, Gdk::Cursor *, uint32_t);
bool motion_handler (GdkEvent*, bool);
void break_drag ();
nframes64_t adjusted_frame (nframes64_t, GdkEvent const *, bool snap = true) const; nframes64_t adjusted_frame (nframes64_t, GdkEvent const *, bool snap = true) const;
nframes64_t adjusted_current_frame (GdkEvent const *, bool snap = true) const; nframes64_t adjusted_current_frame (GdkEvent const *, bool snap = true) const;
@ -156,6 +197,7 @@ protected:
} }
Editor* _editor; ///< our editor Editor* _editor; ///< our editor
DragManager* _drags;
ArdourCanvas::Item* _item; ///< our item ArdourCanvas::Item* _item; ///< our item
/** Offset from the mouse's position for the drag to the start of the thing that is being dragged */ /** Offset from the mouse's position for the drag to the start of the thing that is being dragged */
nframes64_t _pointer_frame_offset; nframes64_t _pointer_frame_offset;
@ -165,17 +207,13 @@ protected:
private: private:
bool _ending; ///< true if end_grab or break_drag is in progress, otherwise false
bool _move_threshold_passed; ///< true if the move threshold has been passed, otherwise false bool _move_threshold_passed; ///< true if the move threshold has been passed, otherwise false
double _grab_x; ///< trackview x of the grab start position double _grab_x; ///< trackview x of the grab start position
double _grab_y; ///< trackview y of the grab start position double _grab_y; ///< trackview y of the grab start position
double _current_pointer_x; ///< trackview x of the current pointer
double _current_pointer_y; ///< trackview y of the current pointer
double _last_pointer_x; ///< trackview x of the pointer last time a motion occurred double _last_pointer_x; ///< trackview x of the pointer last time a motion occurred
double _last_pointer_y; ///< trackview y of the pointer last time a motion occurred double _last_pointer_y; ///< trackview y of the pointer last time a motion occurred
nframes64_t _grab_frame; ///< adjusted_frame that the mouse was at when start_grab was called, or 0 nframes64_t _grab_frame; ///< adjusted_frame that the mouse was at when start_grab was called, or 0
nframes64_t _last_pointer_frame; ///< adjusted_frame the last time a motion occurred nframes64_t _last_pointer_frame; ///< adjusted_frame the last time a motion occurred
nframes64_t _current_pointer_frame; ///< frame that the pointer is now at
}; };

View file

@ -53,10 +53,8 @@ Editor::kbd_driver (sigc::slot<void,GdkEvent*> theslot, bool use_track_canvas, b
/* any use of "keyboard mouse buttons" invalidates an existing grab /* any use of "keyboard mouse buttons" invalidates an existing grab
*/ */
if (_drag) { if (_drags->active ()) {
_drag->item()->ungrab (GDK_CURRENT_TIME); _drags->abort ();
delete _drag;
_drag = 0;
} }
if (doit) { if (doit) {

View file

@ -37,6 +37,7 @@
#include "simplerect.h" #include "simplerect.h"
#include "actions.h" #include "actions.h"
#include "prompter.h" #include "prompter.h"
#include "editor_drag.h"
#include "i18n.h" #include "i18n.h"
@ -1088,7 +1089,7 @@ Editor::new_transport_marker_menu_popdown ()
// hide rects // hide rects
transport_bar_drag_rect->hide(); transport_bar_drag_rect->hide();
break_drag (); _drags->break_drag ();
} }
void void

View file

@ -36,6 +36,7 @@
#include "editor_route_groups.h" #include "editor_route_groups.h"
#include "editor_regions.h" #include "editor_regions.h"
#include "gui_thread.h" #include "gui_thread.h"
#include "editor_drag.h"
#include "i18n.h" #include "i18n.h"
@ -342,7 +343,7 @@ Editor::session_going_away ()
entered_regionview = 0; entered_regionview = 0;
entered_track = 0; entered_track = 0;
last_update_frame = 0; last_update_frame = 0;
_drag = 0; _drags->abort ();
playhead_cursor->canvas_item.hide (); playhead_cursor->canvas_item.hide ();

View file

@ -271,7 +271,7 @@ Editor::set_canvas_cursor ()
void void
Editor::set_mouse_mode (MouseMode m, bool force) Editor::set_mouse_mode (MouseMode m, bool force)
{ {
if (_drag) { if (_drags->active ()) {
return; return;
} }
@ -462,7 +462,7 @@ Editor::button_selection (ArdourCanvas::Item* /*item*/, GdkEvent* event, ItemTyp
set_selected_track_as_side_effect (true); set_selected_track_as_side_effect (true);
} }
if (_join_object_range_state == JOIN_OBJECT_RANGE_OBJECT && !selection->regions.empty()) { if (_join_object_range_state == JOIN_OBJECT_RANGE_OBJECT && !selection->regions.empty()) {
select_range_around_region (selection->regions.front()); clicked_selection = select_range_around_region (selection->regions.front());
} }
break; break;
@ -514,10 +514,8 @@ Editor::button_selection (ArdourCanvas::Item* /*item*/, GdkEvent* event, ItemTyp
bool bool
Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_type) Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_type)
{ {
if (_drag) { if (_drags->active ()) {
_drag->item()->ungrab (event->button.time); _drags->abort ();
delete _drag;
_drag = 0;
} }
/* single mouse clicks on any of these item types operate /* single mouse clicks on any of these item types operate
@ -528,83 +526,73 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
switch (item_type) { switch (item_type) {
case PlayheadCursorItem: case PlayheadCursorItem:
assert (_drag == 0); _drags->set (new CursorDrag (this, item, true), event);
_drag = new CursorDrag (this, item, true);
_drag->start_grab (event);
return true; return true;
case MarkerItem: case MarkerItem:
if (Keyboard::modifier_state_equals (event->button.state, Keyboard::ModifierMask(Keyboard::PrimaryModifier|Keyboard::TertiaryModifier))) { if (Keyboard::modifier_state_equals (event->button.state, Keyboard::ModifierMask(Keyboard::PrimaryModifier|Keyboard::TertiaryModifier))) {
hide_marker (item, event); hide_marker (item, event);
} else { } else {
assert (_drag == 0); _drags->set (new MarkerDrag (this, item), event);
_drag = new MarkerDrag (this, item);
_drag->start_grab (event);
} }
return true; return true;
case TempoMarkerItem: case TempoMarkerItem:
assert (_drag == 0); _drags->set (
_drag = new TempoMarkerDrag ( new TempoMarkerDrag (
this, this,
item, item,
Keyboard::modifier_state_contains (event->button.state, Keyboard::CopyModifier) Keyboard::modifier_state_contains (event->button.state, Keyboard::CopyModifier)
),
event
); );
_drag->start_grab (event);
return true; return true;
case MeterMarkerItem: case MeterMarkerItem:
assert (_drag == 0); _drags->set (
_drag = new MeterMarkerDrag ( new MeterMarkerDrag (
this, this,
item, item,
Keyboard::modifier_state_contains (event->button.state, Keyboard::CopyModifier) Keyboard::modifier_state_contains (event->button.state, Keyboard::CopyModifier)
),
event
); );
_drag->start_grab (event);
return true; return true;
case MarkerBarItem: case MarkerBarItem:
case TempoBarItem: case TempoBarItem:
case MeterBarItem: case MeterBarItem:
if (!Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) { if (!Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) {
assert (_drag == 0); _drags->set (new CursorDrag (this, &playhead_cursor->canvas_item, false), event);
_drag = new CursorDrag (this, &playhead_cursor->canvas_item, false);
_drag->start_grab (event);
} }
return true; return true;
break; break;
case RangeMarkerBarItem: case RangeMarkerBarItem:
assert (_drag == 0);
if (!Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) { if (!Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) {
_drag = new CursorDrag (this, &playhead_cursor->canvas_item, false); _drags->set (new CursorDrag (this, &playhead_cursor->canvas_item, false), event);
} else { } else {
_drag = new RangeMarkerBarDrag (this, item, RangeMarkerBarDrag::CreateRangeMarker); _drags->set (new RangeMarkerBarDrag (this, item, RangeMarkerBarDrag::CreateRangeMarker), event);
} }
_drag->start_grab (event);
return true; return true;
break; break;
case CdMarkerBarItem: case CdMarkerBarItem:
assert (_drag == 0);
if (!Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) { if (!Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) {
_drag = new CursorDrag (this, &playhead_cursor->canvas_item, false); _drags->set (new CursorDrag (this, &playhead_cursor->canvas_item, false), event);
} else { } else {
_drag = new RangeMarkerBarDrag (this, item, RangeMarkerBarDrag::CreateCDMarker); _drags->set (new RangeMarkerBarDrag (this, item, RangeMarkerBarDrag::CreateCDMarker), event);
} }
_drag->start_grab (event);
return true; return true;
break; break;
case TransportMarkerBarItem: case TransportMarkerBarItem:
assert (_drag == 0);
if (!Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) { if (!Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) {
_drag = new CursorDrag (this, &playhead_cursor->canvas_item, false); _drags->set (new CursorDrag (this, &playhead_cursor->canvas_item, false), event);
} else { } else {
_drag = new RangeMarkerBarDrag (this, item, RangeMarkerBarDrag::CreateTransportMarker); _drags->set (new RangeMarkerBarDrag (this, item, RangeMarkerBarDrag::CreateTransportMarker), event);
} }
_drag->start_grab (event);
return true; return true;
break; break;
@ -620,13 +608,9 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
over a region. over a region.
*/ */
if (item_type == StartSelectionTrimItem) { if (item_type == StartSelectionTrimItem) {
assert (_drag == 0); _drags->set (new SelectionDrag (this, item, SelectionDrag::SelectionStartTrim), event);
_drag = new SelectionDrag (this, item, SelectionDrag::SelectionStartTrim);
_drag->start_grab (event);
} else if (item_type == EndSelectionTrimItem) { } else if (item_type == EndSelectionTrimItem) {
assert (_drag == 0); _drags->set (new SelectionDrag (this, item, SelectionDrag::SelectionEndTrim), event);
_drag = new SelectionDrag (this, item, SelectionDrag::SelectionEndTrim);
_drag->start_grab (event);
} }
} }
@ -636,15 +620,11 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
case MouseRange: case MouseRange:
switch (item_type) { switch (item_type) {
case StartSelectionTrimItem: case StartSelectionTrimItem:
assert (_drag == 0); _drags->set (new SelectionDrag (this, item, SelectionDrag::SelectionStartTrim), event);
_drag = new SelectionDrag (this, item, SelectionDrag::SelectionStartTrim);
_drag->start_grab (event);
break; break;
case EndSelectionTrimItem: case EndSelectionTrimItem:
assert (_drag == 0); _drags->set (new SelectionDrag (this, item, SelectionDrag::SelectionEndTrim), event);
_drag = new SelectionDrag (this, item, SelectionDrag::SelectionEndTrim);
_drag->start_grab (event);
break; break;
case SelectionItem: case SelectionItem:
@ -654,32 +634,26 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
start_selection_grab (item, event); start_selection_grab (item, event);
} else if (Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) { } else if (Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) {
/* grab selection for moving */ /* grab selection for moving */
assert (_drag == 0); _drags->set (new SelectionDrag (this, item, SelectionDrag::SelectionMove), event);
_drag = new SelectionDrag (this, item, SelectionDrag::SelectionMove);
_drag->start_grab (event);
} else { } else {
double const y = event->button.y + vertical_adjustment.get_value() - canvas_timebars_vsize; double const y = event->button.y + vertical_adjustment.get_value() - canvas_timebars_vsize;
pair<TimeAxisView*, int> tvp = trackview_by_y_position (y); pair<TimeAxisView*, int> tvp = trackview_by_y_position (y);
if (tvp.first) { if (tvp.first) {
AutomationTimeAxisView* atv = dynamic_cast<AutomationTimeAxisView*> (tvp.first); AutomationTimeAxisView* atv = dynamic_cast<AutomationTimeAxisView*> (tvp.first);
assert (_drag == 0);
if (join_object_range_button.get_active() && atv) { if (join_object_range_button.get_active() && atv) {
/* smart "join" mode: drag automation */ /* smart "join" mode: drag automation */
_drag = new AutomationRangeDrag (this, atv->base_item(), selection->time); _drags->set (new AutomationRangeDrag (this, atv->base_item(), selection->time), event);
} else { } else {
/* this was debated, but decided the more common action was to /* this was debated, but decided the more common action was to
make a new selection */ make a new selection */
_drag = new SelectionDrag (this, item, SelectionDrag::CreateSelection); _drags->set (new SelectionDrag (this, item, SelectionDrag::CreateSelection), event);
} }
_drag->start_grab (event);
} }
} }
break; break;
default: default:
assert (_drag == 0); _drags->set (new SelectionDrag (this, item, SelectionDrag::CreateSelection), event);
_drag = new SelectionDrag (this, item, SelectionDrag::CreateSelection);
_drag->start_grab (event);
} }
return true; return true;
break; break;
@ -689,9 +663,7 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
case NoteItem: case NoteItem:
if (internal_editing()) { if (internal_editing()) {
/* Note: we don't get here if not in internal_editing() mode */ /* Note: we don't get here if not in internal_editing() mode */
assert (_drag == 0); _drags->set (new NoteDrag (this, item), event);
_drag = new NoteDrag (this, item);
_drag->start_grab (event);
return true; return true;
} }
break; break;
@ -703,47 +675,45 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
if (Keyboard::modifier_state_contains (event->button.state, Keyboard::ModifierMask(Keyboard::PrimaryModifier|Keyboard::SecondaryModifier)) && if (Keyboard::modifier_state_contains (event->button.state, Keyboard::ModifierMask(Keyboard::PrimaryModifier|Keyboard::SecondaryModifier)) &&
event->type == GDK_BUTTON_PRESS) { event->type == GDK_BUTTON_PRESS) {
assert (_drag == 0); _drags->set (new RubberbandSelectDrag (this, item), event);
_drag = new RubberbandSelectDrag (this, item);
_drag->start_grab (event);
} else if (event->type == GDK_BUTTON_PRESS) { } else if (event->type == GDK_BUTTON_PRESS) {
switch (item_type) { switch (item_type) {
case FadeInHandleItem: case FadeInHandleItem:
{ {
assert (_drag == 0);
RegionSelection s = get_equivalent_regions (selection->regions, RouteGroup::Edit); RegionSelection s = get_equivalent_regions (selection->regions, RouteGroup::Edit);
_drag = new FadeInDrag (this, item, reinterpret_cast<RegionView*> (item->get_data("regionview")), s); _drags->set (new FadeInDrag (this, item, reinterpret_cast<RegionView*> (item->get_data("regionview")), s), event);
_drag->start_grab (event);
return true; return true;
} }
case FadeOutHandleItem: case FadeOutHandleItem:
{ {
assert (_drag == 0);
RegionSelection s = get_equivalent_regions (selection->regions, RouteGroup::Edit); RegionSelection s = get_equivalent_regions (selection->regions, RouteGroup::Edit);
_drag = new FadeOutDrag (this, item, reinterpret_cast<RegionView*> (item->get_data("regionview")), s); _drags->set (new FadeOutDrag (this, item, reinterpret_cast<RegionView*> (item->get_data("regionview")), s), event);
_drag->start_grab (event);
return true; return true;
} }
case RegionItem: case RegionItem:
if (Keyboard::modifier_state_contains (event->button.state, Keyboard::CopyModifier)) { if (Keyboard::modifier_state_contains (event->button.state, Keyboard::CopyModifier)) {
start_region_copy_grab (item, event, clicked_regionview); add_region_copy_drag (item, event, clicked_regionview);
} else if (Keyboard::the_keyboard().key_is_down (GDK_b)) { } else if (Keyboard::the_keyboard().key_is_down (GDK_b)) {
start_region_brush_grab (item, event, clicked_regionview); add_region_brush_drag (item, event, clicked_regionview);
} else { } else {
start_region_grab (item, event, clicked_regionview); add_region_drag (item, event, clicked_regionview);
} }
if (_join_object_range_state == JOIN_OBJECT_RANGE_OBJECT && !selection->regions.empty()) {
_drags->add (new SelectionDrag (this, clicked_axisview->get_selection_rect (clicked_selection)->rect, SelectionDrag::SelectionMove));
}
_drags->start_grab (event);
break; break;
case RegionViewNameHighlight: case RegionViewNameHighlight:
{ {
assert (_drag == 0);
RegionSelection s = get_equivalent_regions (selection->regions, RouteGroup::Edit); RegionSelection s = get_equivalent_regions (selection->regions, RouteGroup::Edit);
_drag = new TrimDrag (this, item, clicked_regionview, s.by_layer()); _drags->set (new TrimDrag (this, item, clicked_regionview, s.by_layer()), event);
_drag->start_grab (event);
return true; return true;
break; break;
} }
@ -751,61 +721,68 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
case RegionViewName: case RegionViewName:
{ {
/* rename happens on edit clicks */ /* rename happens on edit clicks */
assert (_drag == 0);
RegionSelection s = get_equivalent_regions (selection->regions, RouteGroup::Edit); RegionSelection s = get_equivalent_regions (selection->regions, RouteGroup::Edit);
_drag = new TrimDrag (this, clicked_regionview->get_name_highlight(), clicked_regionview, s.by_layer()); _drags->set (new TrimDrag (this, clicked_regionview->get_name_highlight(), clicked_regionview, s.by_layer()), event);
_drag->start_grab (event);
return true; return true;
break; break;
} }
case ControlPointItem: case ControlPointItem:
assert (_drag == 0); _drags->set (new ControlPointDrag (this, item), event);
_drag = new ControlPointDrag (this, item);
_drag->start_grab (event);
return true; return true;
break; break;
case AutomationLineItem: case AutomationLineItem:
assert (_drag == 0); _drags->set (new LineDrag (this, item), event);
_drag = new LineDrag (this, item);
_drag->start_grab (event);
return true; return true;
break; break;
case StreamItem: case StreamItem:
if (internal_editing()) { if (internal_editing()) {
assert (_drag == 0); _drags->set (new RegionCreateDrag (this, item, clicked_axisview), event);
_drag = new RegionCreateDrag (this, item, clicked_axisview);
_drag->start_grab (event);
return true; return true;
} else { } else {
assert (_drag == 0); _drags->set (new RubberbandSelectDrag (this, item), event);
_drag = new RubberbandSelectDrag (this, item);
_drag->start_grab (event);
} }
break; break;
case AutomationTrackItem: case AutomationTrackItem:
assert (_drag == 0);
/* rubberband drag to select automation points */ /* rubberband drag to select automation points */
_drag = new RubberbandSelectDrag (this, item); _drags->set (new RubberbandSelectDrag (this, item), event);
_drag->start_grab (event);
break; break;
case SelectionItem: case SelectionItem:
{ {
if (join_object_range_button.get_active()) { if (join_object_range_button.get_active()) {
/* we're in "smart" joined mode, and we've clicked on a Selection; if we're /* we're in "smart" joined mode, and we've clicked on a Selection */
* over an automation track, start a drag of its data */
double const y = event->button.y + vertical_adjustment.get_value() - canvas_timebars_vsize; double const y = event->button.y + vertical_adjustment.get_value() - canvas_timebars_vsize;
pair<TimeAxisView*, int> tvp = trackview_by_y_position (y); pair<TimeAxisView*, int> tvp = trackview_by_y_position (y);
if (tvp.first) { if (tvp.first) {
/* if we're over an automation track, start a drag of its data */
AutomationTimeAxisView* atv = dynamic_cast<AutomationTimeAxisView*> (tvp.first); AutomationTimeAxisView* atv = dynamic_cast<AutomationTimeAxisView*> (tvp.first);
if (atv) { if (atv) {
assert (_drag == 0); _drags->set (new AutomationRangeDrag (this, atv->base_item(), selection->time), event);
_drag = new AutomationRangeDrag (this, atv->base_item(), selection->time); }
_drag->start_grab (event);
/* if we're over a track and a region, and in the `object' part of a region,
put a selection around the region and drag both
*/
RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (tvp.first);
if (rtv && _join_object_range_state == JOIN_OBJECT_RANGE_OBJECT) {
boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track> (rtv->route ());
if (t) {
boost::shared_ptr<Playlist> pl = t->diskstream()->playlist ();
if (pl) {
boost::shared_ptr<Region> r = pl->top_region_at (unit_to_frame (event->button.x));
RegionView* rv = rtv->view()->find_view (r);
clicked_selection = select_range_around_region (rv);
_drags->add (new SelectionDrag (this, item, SelectionDrag::SelectionMove));
list<RegionView*> rvs;
rvs.push_back (rv);
_drags->add (new RegionMoveDrag (this, item, rv, rvs, false, false));
_drags->start_grab (event);
}
}
} }
} }
} }
@ -854,21 +831,15 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
/* start a grab so that if we finish after moving /* start a grab so that if we finish after moving
we can tell what happened. we can tell what happened.
*/ */
assert (_drag == 0); _drags->set (new RegionGainDrag (this, item), event, current_canvas_cursor);
_drag = new RegionGainDrag (this, item);
_drag->start_grab (event, current_canvas_cursor);
break; break;
case GainLineItem: case GainLineItem:
assert (_drag == 0); _drags->set (new LineDrag (this, item), event);
_drag = new LineDrag (this, item);
_drag->start_grab (event);
return true; return true;
case ControlPointItem: case ControlPointItem:
assert (_drag == 0); _drags->set (new ControlPointDrag (this, item), event);
_drag = new ControlPointDrag (this, item);
_drag->start_grab (event);
return true; return true;
break; break;
@ -880,15 +851,11 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
switch (item_type) { switch (item_type) {
case ControlPointItem: case ControlPointItem:
assert (_drag == 0); _drags->set (new ControlPointDrag (this, item), event);
_drag = new ControlPointDrag (this, item);
_drag->start_grab (event);
break; break;
case AutomationLineItem: case AutomationLineItem:
assert (_drag == 0); _drags->set (new LineDrag (this, item), event);
_drag = new LineDrag (this, item);
_drag->start_grab (event);
break; break;
case RegionItem: case RegionItem:
@ -905,9 +872,7 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
case MouseZoom: case MouseZoom:
if (event->type == GDK_BUTTON_PRESS) { if (event->type == GDK_BUTTON_PRESS) {
assert (_drag == 0); _drags->set (new MouseZoomDrag (this, item), event);
_drag = new MouseZoomDrag (this, item);
_drag->start_grab (event);
} }
return true; return true;
@ -915,21 +880,16 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
case MouseTimeFX: case MouseTimeFX:
if (internal_editing() && item_type == NoteItem) { if (internal_editing() && item_type == NoteItem) {
assert (_drag == 0); _drags->set (new NoteResizeDrag (this, item), event);
_drag = new NoteResizeDrag (this, item);
_drag->start_grab (event);
return true; return true;
} else if (!internal_editing() && item_type == RegionItem) { } else if (!internal_editing() && item_type == RegionItem) {
assert (_drag == 0); _drags->set (new TimeFXDrag (this, item, clicked_regionview, selection->regions.by_layer()), event);
_drag = new TimeFXDrag (this, item, clicked_regionview, selection->regions.by_layer());
_drag->start_grab (event);
return true; return true;
} }
break; break;
case MouseAudition: case MouseAudition:
_drag = new ScrubDrag (this, item); _drags->set (new ScrubDrag (this, item), event);
_drag->start_grab (event);
scrub_reversals = 0; scrub_reversals = 0;
scrub_reverse_distance = 0; scrub_reverse_distance = 0;
last_scrub_x = event->button.x; last_scrub_x = event->button.x;
@ -954,16 +914,15 @@ Editor::button_press_handler_2 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
switch (item_type) { switch (item_type) {
case RegionItem: case RegionItem:
if (Keyboard::modifier_state_contains (event->button.state, Keyboard::CopyModifier)) { if (Keyboard::modifier_state_contains (event->button.state, Keyboard::CopyModifier)) {
start_region_copy_grab (item, event, clicked_regionview); add_region_copy_drag (item, event, clicked_regionview);
} else { } else {
start_region_grab (item, event, clicked_regionview); add_region_drag (item, event, clicked_regionview);
} }
_drags->start_grab (event);
return true; return true;
break; break;
case ControlPointItem: case ControlPointItem:
assert (_drag == 0); _drags->set (new ControlPointDrag (this, item), event);
_drag = new ControlPointDrag (this, item);
_drag->start_grab (event);
return true; return true;
break; break;
@ -973,16 +932,12 @@ Editor::button_press_handler_2 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
switch (item_type) { switch (item_type) {
case RegionViewNameHighlight: case RegionViewNameHighlight:
assert (_drag == 0); _drags->set (new TrimDrag (this, item, clicked_regionview, selection->regions.by_layer()), event);
_drag = new TrimDrag (this, item, clicked_regionview, selection->regions.by_layer());
_drag->start_grab (event);
return true; return true;
break; break;
case RegionViewName: case RegionViewName:
assert (_drag == 0); _drags->set (new TrimDrag (this, clicked_regionview->get_name_highlight(), clicked_regionview, selection->regions.by_layer()), event);
_drag = new TrimDrag (this, clicked_regionview->get_name_highlight(), clicked_regionview, selection->regions.by_layer());
_drag->start_grab (event);
return true; return true;
break; break;
@ -1047,7 +1002,7 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp
button_selection (item, event, item_type); button_selection (item, event, item_type);
if (_drag == 0 && if (!_drags->active () &&
(Keyboard::is_delete_event (&event->button) || (Keyboard::is_delete_event (&event->button) ||
Keyboard::is_context_menu_event (&event->button) || Keyboard::is_context_menu_event (&event->button) ||
Keyboard::is_edit_event (&event->button))) { Keyboard::is_edit_event (&event->button))) {
@ -1091,10 +1046,8 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT
/* first, see if we're finishing a drag ... */ /* first, see if we're finishing a drag ... */
bool were_dragging = false; bool were_dragging = false;
if (_drag) { if (_drags->active ()) {
bool const r = _drag->end_grab (event); bool const r = _drags->end_grab (event);
delete _drag;
_drag = 0;
if (r) { if (r) {
/* grab dragged, so do nothing else */ /* grab dragged, so do nothing else */
return true; return true;
@ -1107,7 +1060,7 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT
/* edit events get handled here */ /* edit events get handled here */
if (_drag == 0 && Keyboard::is_edit_event (&event->button)) { if (!_drags->active () && Keyboard::is_edit_event (&event->button)) {
switch (item_type) { switch (item_type) {
case RegionItem: case RegionItem:
edit_region (); edit_region ();
@ -1141,7 +1094,7 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT
if (Keyboard::is_context_menu_event (&event->button)) { if (Keyboard::is_context_menu_event (&event->button)) {
if (_drag == 0) { if (!_drags->active ()) {
/* no matter which button pops up the context menu, tell the menu /* no matter which button pops up the context menu, tell the menu
widget to use button 1 to drive menu selection. widget to use button 1 to drive menu selection.
@ -1225,7 +1178,7 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT
Editing::MouseMode const eff = effective_mouse_mode (); Editing::MouseMode const eff = effective_mouse_mode ();
if (_drag == 0 && Keyboard::is_delete_event (&event->button)) { if (!_drags->active () && Keyboard::is_delete_event (&event->button)) {
switch (item_type) { switch (item_type) {
case TempoMarkerItem: case TempoMarkerItem:
@ -1447,7 +1400,7 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
fraction = 1.0 - (cp->get_y() / cp->line().height()); fraction = 1.0 - (cp->get_y() / cp->line().height());
if (is_drawable() && dynamic_cast<ScrubDrag*> (_drag) == 0) { if (is_drawable() && !_drags->active ()) {
track_canvas->get_window()->set_cursor (*fader_cursor); track_canvas->get_window()->set_cursor (*fader_cursor);
} }
@ -1734,10 +1687,6 @@ Editor::leave_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
break; break;
} }
if (item_type == RegionItem) {
update_join_object_range_location (event->crossing.x, event->crossing.y);
}
return false; return false;
} }
@ -1752,19 +1701,19 @@ Editor::left_automation_track ()
} }
void void
Editor::scrub () Editor::scrub (nframes64_t frame, double current_x)
{ {
double delta; double delta;
if (scrubbing_direction == 0) { if (scrubbing_direction == 0) {
/* first move */ /* first move */
_session->request_locate (_drag->adjusted_current_frame (0), false); _session->request_locate (frame, false);
_session->request_transport_speed (0.1); _session->request_transport_speed (0.1);
scrubbing_direction = 1; scrubbing_direction = 1;
} else { } else {
if (last_scrub_x > _drag->current_pointer_x()) { if (last_scrub_x > current_x) {
/* pointer moved to the left */ /* pointer moved to the left */
@ -1773,7 +1722,7 @@ Editor::scrub ()
/* we reversed direction to go backwards */ /* we reversed direction to go backwards */
scrub_reversals++; scrub_reversals++;
scrub_reverse_distance += (int) (last_scrub_x - _drag->current_pointer_x()); scrub_reverse_distance += (int) (last_scrub_x - current_x);
} else { } else {
@ -1782,7 +1731,7 @@ Editor::scrub ()
scrub_reversals = 0; scrub_reversals = 0;
scrub_reverse_distance = 0; scrub_reverse_distance = 0;
delta = 0.01 * (last_scrub_x - _drag->current_pointer_x()); delta = 0.01 * (last_scrub_x - current_x);
_session->request_transport_speed (_session->transport_speed() - delta); _session->request_transport_speed (_session->transport_speed() - delta);
} }
@ -1793,7 +1742,7 @@ Editor::scrub ()
/* we reversed direction to go forward */ /* we reversed direction to go forward */
scrub_reversals++; scrub_reversals++;
scrub_reverse_distance += (int) (_drag->current_pointer_x() - last_scrub_x); scrub_reverse_distance += (int) (current_x - last_scrub_x);
} else { } else {
/* still moving to the right */ /* still moving to the right */
@ -1801,7 +1750,7 @@ Editor::scrub ()
scrub_reversals = 0; scrub_reversals = 0;
scrub_reverse_distance = 0; scrub_reverse_distance = 0;
delta = 0.01 * (_drag->current_pointer_x() - last_scrub_x); delta = 0.01 * (current_x - last_scrub_x);
_session->request_transport_speed (_session->transport_speed() + delta); _session->request_transport_speed (_session->transport_speed() + delta);
} }
} }
@ -1827,7 +1776,7 @@ Editor::scrub ()
} }
} }
last_scrub_x = _drag->current_pointer_x(); last_scrub_x = current_x;
} }
bool bool
@ -1866,8 +1815,8 @@ Editor::motion_handler (ArdourCanvas::Item* /*item*/, GdkEvent* event, bool from
} }
bool handled = false; bool handled = false;
if (_drag) { if (_drags->active ()) {
handled = _drag->motion_handler (event, from_autoscroll); handled = _drags->motion_handler (event, from_autoscroll);
} }
if (!handled) { if (!handled) {
@ -2042,7 +1991,7 @@ Editor::show_verbose_time_cursor (nframes64_t frame, double offset, double xpos,
if (xpos >= 0 && ypos >=0) { if (xpos >= 0 && ypos >=0) {
set_verbose_canvas_cursor (buf, xpos + offset, ypos + offset); set_verbose_canvas_cursor (buf, xpos + offset, ypos + offset);
} else { } else {
set_verbose_canvas_cursor (buf, _drag->current_pointer_x() + offset - horizontal_adjustment.get_value(), _drag->current_pointer_y() + offset - vertical_adjustment.get_value() + canvas_timebars_vsize); set_verbose_canvas_cursor (buf, _drags->current_pointer_x() + offset - horizontal_adjustment.get_value(), _drags->current_pointer_y() + offset - vertical_adjustment.get_value() + canvas_timebars_vsize);
} }
show_verbose_canvas_cursor (); show_verbose_canvas_cursor ();
} }
@ -2124,7 +2073,7 @@ Editor::show_verbose_duration_cursor (nframes64_t start, nframes64_t end, double
set_verbose_canvas_cursor (buf, xpos + offset, ypos + offset); set_verbose_canvas_cursor (buf, xpos + offset, ypos + offset);
} }
else { else {
set_verbose_canvas_cursor (buf, _drag->current_pointer_x() + offset, _drag->current_pointer_y() + offset); set_verbose_canvas_cursor (buf, _drags->current_pointer_x() + offset, _drags->current_pointer_y() + offset);
} }
show_verbose_canvas_cursor (); show_verbose_canvas_cursor ();
@ -2310,14 +2259,10 @@ Editor::single_end_trim (RegionView& rv, nframes64_t frame_delta, bool left_dire
void void
Editor::point_trim (GdkEvent* event) Editor::point_trim (GdkEvent* event, nframes64_t new_bound)
{ {
RegionView* rv = clicked_regionview; RegionView* rv = clicked_regionview;
nframes64_t new_bound = _drag->adjusted_current_frame (event);
snap_to_with_modifier (new_bound, event);
/* Choose action dependant on which button was pressed */ /* Choose action dependant on which button was pressed */
switch (event->button.button) { switch (event->button.button) {
case 1: case 1:
@ -2519,23 +2464,19 @@ Editor::track_height_step_timeout ()
} }
void void
Editor::start_region_grab (ArdourCanvas::Item* item, GdkEvent* event, RegionView* region_view) Editor::add_region_drag (ArdourCanvas::Item* item, GdkEvent* event, RegionView* region_view)
{ {
assert (region_view); assert (region_view);
_region_motion_group->raise_to_top (); _region_motion_group->raise_to_top ();
assert (_drag == 0);
if (Config->get_edit_mode() == Splice) { if (Config->get_edit_mode() == Splice) {
_drag = new RegionSpliceDrag (this, item, region_view, selection->regions.by_layer()); _drags->add (new RegionSpliceDrag (this, item, region_view, selection->regions.by_layer()));
} else { } else {
RegionSelection s = get_equivalent_regions (selection->regions, RouteGroup::Edit); RegionSelection s = get_equivalent_regions (selection->regions, RouteGroup::Edit);
_drag = new RegionMoveDrag (this, item, region_view, s.by_layer(), false, false); _drags->add (new RegionMoveDrag (this, item, region_view, s.by_layer(), false, false));
} }
_drag->start_grab (event);
begin_reversible_command (_("move region(s)")); begin_reversible_command (_("move region(s)"));
/* sync the canvas to what we think is its current state */ /* sync the canvas to what we think is its current state */
@ -2543,31 +2484,27 @@ Editor::start_region_grab (ArdourCanvas::Item* item, GdkEvent* event, RegionView
} }
void void
Editor::start_region_copy_grab (ArdourCanvas::Item* item, GdkEvent* event, RegionView* region_view) Editor::add_region_copy_drag (ArdourCanvas::Item* item, GdkEvent* event, RegionView* region_view)
{ {
assert (region_view); assert (region_view);
assert (_drag == 0);
_region_motion_group->raise_to_top (); _region_motion_group->raise_to_top ();
RegionSelection s = get_equivalent_regions (selection->regions, RouteGroup::Edit); RegionSelection s = get_equivalent_regions (selection->regions, RouteGroup::Edit);
_drag = new RegionMoveDrag (this, item, region_view, s.by_layer(), false, true); _drags->add (new RegionMoveDrag (this, item, region_view, s.by_layer(), false, true));
_drag->start_grab(event);
} }
void void
Editor::start_region_brush_grab (ArdourCanvas::Item* item, GdkEvent* event, RegionView* region_view) Editor::add_region_brush_drag (ArdourCanvas::Item* item, GdkEvent* event, RegionView* region_view)
{ {
assert (region_view); assert (region_view);
assert (_drag == 0);
if (Config->get_edit_mode() == Splice) { if (Config->get_edit_mode() == Splice) {
return; return;
} }
RegionSelection s = get_equivalent_regions (selection->regions, RouteGroup::Edit); RegionSelection s = get_equivalent_regions (selection->regions, RouteGroup::Edit);
_drag = new RegionMoveDrag (this, item, region_view, s.by_layer(), true, false); _drags->add (new RegionMoveDrag (this, item, region_view, s.by_layer(), true, false));
_drag->start_grab (event);
begin_reversible_command (_("Drag region brush")); begin_reversible_command (_("Drag region brush"));
} }
@ -2633,31 +2570,19 @@ Editor::start_selection_grab (ArdourCanvas::Item* /*item*/, GdkEvent* event)
*/ */
selection->set (latest_regionviews); selection->set (latest_regionviews);
assert (_drag == 0); _drags->set (new RegionMoveDrag (this, latest_regionviews.front()->get_canvas_group(), latest_regionviews.front(), latest_regionviews, false, false), event);
_drag = new RegionMoveDrag (this, latest_regionviews.front()->get_canvas_group(), latest_regionviews.front(), latest_regionviews, false, false);
_drag->start_grab (event);
} }
void void
Editor::escape () Editor::escape ()
{ {
if (_drag) { if (_drags->active ()) {
break_drag (); _drags->break_drag ();
} else { } else {
selection->clear (); selection->clear ();
} }
} }
void
Editor::break_drag ()
{
if (_drag) {
_drag->break_drag ();
delete _drag;
_drag = 0;
}
}
void void
Editor::set_internal_edit (bool yn) Editor::set_internal_edit (bool yn)
{ {
@ -2700,33 +2625,37 @@ Editor::set_internal_edit (bool yn)
void void
Editor::update_join_object_range_location (double x, double y) Editor::update_join_object_range_location (double x, double y)
{ {
/* XXX: actually, this decides based on whether the mouse is in the top or bottom half of a RouteTimeAxisView;
entered_{track,regionview} is not always setup (e.g. if the mouse is over a TimeSelection), and to get a Region
that we're over requires searching the playlist.
*/
if (join_object_range_button.get_active() == false || (mouse_mode != MouseRange && mouse_mode != MouseObject)) { if (join_object_range_button.get_active() == false || (mouse_mode != MouseRange && mouse_mode != MouseObject)) {
_join_object_range_state = JOIN_OBJECT_RANGE_NONE; _join_object_range_state = JOIN_OBJECT_RANGE_NONE;
return; return;
} }
if (entered_regionview) { if (mouse_mode == MouseObject) {
_join_object_range_state = JOIN_OBJECT_RANGE_OBJECT;
} else if (mouse_mode == MouseRange) {
_join_object_range_state = JOIN_OBJECT_RANGE_RANGE;
}
double cx = x; /* XXX: maybe we should make entered_track work in all cases, rather than resorting to this */
double cy = y; pair<TimeAxisView*, int> tvp = trackview_by_y_position (y + vertical_adjustment.get_value() - canvas_timebars_vsize);
entered_regionview->get_canvas_group()->w2i (cx, cy);
double x1; if (tvp.first) {
double y1;
double x2;
double y2;
entered_regionview->get_canvas_group()->get_bounds (x1, y1, x2, y2);
bool const top_half = cy < (y2 - y1) / 2; RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (tvp.first);
if (rtv) {
_join_object_range_state = top_half ? JOIN_OBJECT_RANGE_RANGE : JOIN_OBJECT_RANGE_OBJECT; double cx = 0;
double cy = y;
rtv->canvas_display()->w2i (cx, cy);
} else { bool const top_half = cy < rtv->current_height () / 2;
if (mouse_mode == MouseObject) { _join_object_range_state = top_half ? JOIN_OBJECT_RANGE_RANGE : JOIN_OBJECT_RANGE_OBJECT;
_join_object_range_state = JOIN_OBJECT_RANGE_OBJECT;
} else if (mouse_mode == MouseRange) {
_join_object_range_state = JOIN_OBJECT_RANGE_RANGE;
} }
} }
} }

View file

@ -3826,10 +3826,8 @@ Editor::cut_copy (CutCopyOp op)
*/ */
if (op == Cut || op == Clear) { if (op == Cut || op == Clear) {
if (_drag) { if (_drags->active ()) {
_drag->item()->ungrab (0); _drags->abort ();
delete _drag;
_drag = 0;
} }
} }
@ -3846,10 +3844,7 @@ Editor::cut_copy (CutCopyOp op)
Glib::signal_idle().connect (sigc::bind (sigc::mem_fun(*this, &Editor::really_remove_marker), loc)); Glib::signal_idle().connect (sigc::bind (sigc::mem_fun(*this, &Editor::really_remove_marker), loc));
} }
break_drag (); _drags->break_drag ();
delete _drag;
_drag = 0;
return; return;
} }
@ -3930,9 +3925,7 @@ Editor::cut_copy (CutCopyOp op)
} }
if (op == Cut || op == Clear) { if (op == Cut || op == Clear) {
break_drag (); _drags->break_drag ();
delete _drag;
_drag = 0;
} }
} }

View file

@ -246,9 +246,7 @@ Editor::ruler_button_press (GdkEventButton* ev)
} }
/* playhead cursor */ /* playhead cursor */
assert (_drag == 0); _drags->set (new CursorDrag (this, &playhead_cursor->canvas_item, false), reinterpret_cast<GdkEvent *> (ev));
_drag = new CursorDrag (this, &playhead_cursor->canvas_item, false);
_drag->start_grab (reinterpret_cast<GdkEvent *> (ev));
_dragging_playhead = true; _dragging_playhead = true;
} }
@ -265,10 +263,8 @@ Editor::ruler_button_release (GdkEventButton* ev)
gint x,y; gint x,y;
Gdk::ModifierType state; Gdk::ModifierType state;
if (_drag) { if (_drags->active ()) {
_drag->end_grab (reinterpret_cast<GdkEvent*> (ev)); _drags->end_grab (reinterpret_cast<GdkEvent*> (ev));
delete _drag;
_drag = 0;
_dragging_playhead = false; _dragging_playhead = false;
} }
@ -312,8 +308,8 @@ Editor::ruler_mouse_motion (GdkEventMotion* ev)
return FALSE; return FALSE;
} }
if (_drag) { if (_drags->active ()) {
_drag->motion_handler (reinterpret_cast<GdkEvent*> (ev), false); _drags->motion_handler (reinterpret_cast<GdkEvent*> (ev), false);
} }
return TRUE; return TRUE;

View file

@ -1418,12 +1418,12 @@ Editor::deselect_all ()
selection->clear (); selection->clear ();
} }
void long
Editor::select_range_around_region (RegionView* rv) Editor::select_range_around_region (RegionView* rv)
{ {
selection->set (&rv->get_time_axis_view()); selection->set (&rv->get_time_axis_view());
selection->time.clear (); selection->time.clear ();
boost::shared_ptr<Region> r = rv->region (); boost::shared_ptr<Region> r = rv->region ();
selection->set (r->position(), r->position() + r->length()); return selection->set (r->position(), r->position() + r->length());
} }

View file

@ -221,6 +221,8 @@ class TimeAxisView : public virtual AxisView, public PBD::Stateful
typedef std::vector<boost::shared_ptr<TimeAxisView> > Children; typedef std::vector<boost::shared_ptr<TimeAxisView> > Children;
SelectionRect* get_selection_rect(uint32_t id);
protected: protected:
/* The Standard LHS Controls */ /* The Standard LHS Controls */
Gtk::HBox controls_hbox; Gtk::HBox controls_hbox;
@ -317,8 +319,6 @@ class TimeAxisView : public virtual AxisView, public PBD::Stateful
std::list<SelectionRect*> free_selection_rects; std::list<SelectionRect*> free_selection_rects;
std::list<SelectionRect*> used_selection_rects; std::list<SelectionRect*> used_selection_rects;
SelectionRect* get_selection_rect(uint32_t id);
virtual void selection_click (GdkEventButton*); virtual void selection_click (GdkEventButton*);
bool _hidden; bool _hidden;