X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Feditor_drag.cc;h=0b5b789e9e6e1e2943ae0e6b11ae6a3cb97f2742;hb=5ef06dd439088226683beff5c6fc1d5af55a014b;hp=04dedf97ad4c05d2702b8282f10a9dbca96d4e04;hpb=0938a42440cc82ce8d0cb064840c258c863714ab;p=ardour.git diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc index 04dedf97ad..0b5b789e9e 100644 --- a/gtk2_ardour/editor_drag.cc +++ b/gtk2_ardour/editor_drag.cc @@ -29,10 +29,12 @@ #include "gtkmm2ext/utils.h" -#include "ardour/session.h" +#include "ardour/audioregion.h" #include "ardour/dB.h" -#include "ardour/region_factory.h" +#include "ardour/midi_region.h" #include "ardour/operations.h" +#include "ardour/region_factory.h" +#include "ardour/session.h" #include "editor.h" #include "i18n.h" @@ -409,20 +411,19 @@ RegionDrag::RegionDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, listvisible_order_range (&_visible_y_low, &_visible_y_high); - /* Make a list of non-hidden tracks to refer to during the drag */ + /* Make a list of tracks to refer to during the drag; we include hidden tracks, + as some of the regions we are dragging may be on such tracks. + */ TrackViewList track_views = _editor->track_views; track_views.sort (EditorOrderTimeAxisViewSorter ()); for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) { - if (!(*i)->hidden()) { - - _time_axis_views.push_back (*i); - - TimeAxisView::Children children_list = (*i)->get_child_list (); - for (TimeAxisView::Children::iterator j = children_list.begin(); j != children_list.end(); ++j) { - _time_axis_views.push_back (j->get()); - } + _time_axis_views.push_back (*i); + + TimeAxisView::Children children_list = (*i)->get_child_list (); + for (TimeAxisView::Children::iterator j = children_list.begin(); j != children_list.end(); ++j) { + _time_axis_views.push_back (j->get()); } } @@ -449,7 +450,9 @@ RegionDrag::region_going_away (RegionView* v) } } -/** Given a non-hidden TimeAxisView, return the index of it into the _time_axis_views vector */ +/** Given a TimeAxisView, return the index of it into the _time_axis_views vector, + * or -1 if it is not found. + */ int RegionDrag::find_time_axis_view (TimeAxisView* t) const { @@ -633,49 +636,24 @@ RegionMotionDrag::motion (GdkEvent* event, bool first_move) if (first_move) { - /* here we are calculating the y distance from the - top of the first track view to the top of the region - area of the track view that we're working on */ - - /* this x value is just a dummy value so that we have something - to pass to i2w () */ - - double ix1 = 0; - - /* distance from the top of this track view to the region area - of our track view is always 1 */ - - double iy1 = 1; - - /* convert to world coordinates, ie distance from the top of - the ruler section */ - - rv->get_canvas_frame()->i2w (ix1, iy1); - - /* compensate for the ruler section and the vertical scrollbar position */ - iy1 += _editor->get_trackview_group_vertical_offset (); - - // hide any dependent views - rv->get_time_axis_view().hide_dependent_views (*rv); - - /* - reparent to a non scrolling group so that we can keep the - region selection above all time axis views. - reparenting means we have to move the rv as the two - parent groups have different coordinates. + + /* Reparent to a non scrolling group so that we can keep the + region selection above all time axis views. + Reparenting means that we will have to move the region view + later, as the two parent groups have different coordinates. */ - - rv->get_canvas_group()->property_y() = iy1 - 1; + rv->get_canvas_group()->reparent (*(_editor->_region_motion_group)); - + rv->fake_set_opaque (true); + + if (!rv->get_time_axis_view().hidden()) { + /* the track that this region view is on is hidden, so hide the region too */ + rv->get_canvas_group()->hide (); + } } - /* Work out the change in y position of this region view */ - - double y_delta = 0; - /* If we have moved tracks, we'll fudge the layer delta so that the region gets moved back onto layer 0 on its new track; this avoids confusion when dragging regions from non-zero layers onto different @@ -686,33 +664,21 @@ RegionMotionDrag::motion (GdkEvent* event, bool first_move) this_delta_layer = - i->layer; } - /* Move this region to layer 0 on its old track */ - StreamView* lv = _time_axis_views[i->time_axis_view]->view (); - if (lv->layer_display() == Stacked) { - y_delta -= (lv->layers() - i->layer - 1) * lv->child_height (); - } - - /* Now move it to its right layer on the current track */ - StreamView* cv = _time_axis_views[i->time_axis_view + delta_time_axis_view]->view (); - if (cv->layer_display() == Stacked) { - y_delta += (cv->layers() - (i->layer + this_delta_layer) - 1) * cv->child_height (); - } + /* The TimeAxisView that this region is now on */ + TimeAxisView* tv = _time_axis_views[i->time_axis_view + delta_time_axis_view]; + + /* Set height */ + rv->set_height (tv->view()->child_height ()); - /* Move tracks */ - if (delta_time_axis_view > 0) { - for (int j = 0; j < delta_time_axis_view; ++j) { - y_delta += _time_axis_views[i->time_axis_view + j]->current_height (); - } + /* Update show/hidden status as the region view may have come from a hidden track, + or have moved to one. + */ + if (tv->hidden ()) { + rv->get_canvas_group()->hide (); } else { - /* start by subtracting the height of the track above where we are now */ - for (int j = 1; j <= -delta_time_axis_view; ++j) { - y_delta -= _time_axis_views[i->time_axis_view - j]->current_height (); - } + rv->get_canvas_group()->show (); } - /* Set height */ - rv->set_height (_time_axis_views[i->time_axis_view + delta_time_axis_view]->view()->child_height ()); - /* Update the DraggingView */ i->time_axis_view += delta_time_axis_view; i->layer += this_delta_layer; @@ -720,7 +686,21 @@ RegionMotionDrag::motion (GdkEvent* event, bool first_move) if (_brushing) { _editor->mouse_brush_insert_region (rv, pending_region_position); } else { - rv->move (x_delta, y_delta); + double x = 0; + double y = 0; + + /* Get the y coordinate of the top of the track that this region is now on */ + tv->canvas_display()->i2w (x, y); + y += _editor->get_trackview_group_vertical_offset(); + + /* And adjust for the layer that it should be on */ + StreamView* cv = tv->view (); + if (cv->layer_display() == Stacked) { + y += (cv->layers() - i->layer - 1) * cv->child_height (); + } + + /* Now move the region view */ + rv->move (x_delta, y - rv->get_canvas_group()->property_y()); } } /* foreach region */ @@ -826,10 +806,18 @@ RegionMoveDrag::finished (GdkEvent *, bool movement_occurred) assert (!_views.empty ()); + /* We might have hidden region views so that they weren't visible during the drag + (when they have been reparented). Now everything can be shown again, as region + views are back in their track parent groups. + */ + for (list::iterator i = _views.begin(); i != _views.end(); ++i) { + i->view->get_canvas_group()->show (); + } + bool const changed_position = (_last_frame_position != _primary->region()->position()); bool const changed_tracks = (_time_axis_views[_views.front().time_axis_view] != &_views.front().view->get_time_axis_view()); framecnt_t const drag_delta = _primary->region()->position() - _last_frame_position; - + _editor->update_canvas_now (); if (_copy) { @@ -1541,7 +1529,10 @@ NoteResizeDrag::finished (GdkEvent*, bool /*movement_occurred*/) void NoteResizeDrag::aborted (bool) { - /* XXX: TODO */ + MidiRegionSelection& ms (_editor->get_selection().midi_regions); + for (MidiRegionSelection::iterator r = ms.begin(); r != ms.end(); ++r) { + (*r)->abort_resizing (); + } } RegionGainDrag::RegionGainDrag (Editor* e, ArdourCanvas::Item* i) @@ -2106,39 +2097,6 @@ CursorDrag::start_grab (GdkEvent* event, Gdk::Cursor* c) void CursorDrag::motion (GdkEvent* event, bool) { - if (_drags->current_pointer_y() != last_pointer_y()) { - - /* zoom when we move the pointer up and down */ - - /* y range to operate over (pixels) */ - double const y_range = 512; - /* we will multiply the grab zoom by a factor between scale_range and scale_range^-1 */ - double const scale_range = 4; - /* dead zone around the grab point in which to do no zooming (pixels) */ - double const dead_zone = 100; - - /* current dy */ - double dy = _drags->current_pointer_y() - grab_y(); - - if (dy < -dead_zone || dy > dead_zone) { - /* we are outside the dead zone; remove it from our calculation */ - if (dy < 0) { - dy += dead_zone; - } else { - dy -= dead_zone; - } - - /* get a number from -1 to 1 as dy ranges from -y_range to y_range */ - double udy = max (min (dy / y_range, 1.0), -1.0); - - /* and zoom, using playhead focus temporarily */ - Editing::ZoomFocus const zf = _editor->get_zoom_focus (); - _editor->set_zoom_focus (Editing::ZoomFocusPlayhead); - _editor->temporal_zoom (_grab_zoom * pow (scale_range, -udy)); - _editor->set_zoom_focus (zf); - } - } - framepos_t const adjusted_frame = adjusted_current_frame (event); if (adjusted_frame != last_pointer_frame()) { fake_locate (adjusted_frame); @@ -3112,7 +3070,37 @@ RubberbandSelectDrag::motion (GdkEvent* event, bool) _editor->rubberband_rect->raise_to_top(); show_verbose_cursor_time (pf); + + do_select_things (event, true); + } +} + +void +RubberbandSelectDrag::do_select_things (GdkEvent* event, bool drag_in_progress) +{ + framepos_t x1; + framepos_t x2; + + if (grab_frame() < last_pointer_frame()) { + x1 = grab_frame (); + x2 = last_pointer_frame (); + } else { + x2 = grab_frame (); + x1 = last_pointer_frame (); } + + double y1; + double y2; + + if (_drags->current_pointer_y() < grab_y()) { + y1 = _drags->current_pointer_y(); + y2 = grab_y(); + } else { + y2 = _drags->current_pointer_y(); + y1 = grab_y(); + } + + select_things (event->button.state, x1, x2, y1, y2, drag_in_progress); } void @@ -3121,36 +3109,12 @@ RubberbandSelectDrag::finished (GdkEvent* event, bool movement_occurred) if (movement_occurred) { motion (event, false); + do_select_things (event, false); - double y1,y2; - if (_drags->current_pointer_y() < grab_y()) { - y1 = _drags->current_pointer_y(); - y2 = grab_y(); - } else { - y2 = _drags->current_pointer_y(); - y1 = grab_y(); - } - - - Selection::Operation op = ArdourKeyboard::selection_type (event->button.state); - - _editor->begin_reversible_command (_("rubberband selection")); - - if (grab_frame() < last_pointer_frame()) { - _editor->select_all_within (grab_frame(), last_pointer_frame() - 1, y1, y2, _editor->track_views, op, false); - } else { - _editor->select_all_within (last_pointer_frame(), grab_frame() - 1, y1, y2, _editor->track_views, op, false); - } + } else { - _editor->commit_reversible_command (); + deselect_things (); - } else { - if (!getenv("ARDOUR_SAE")) { - _editor->selection->clear_tracks(); - } - _editor->selection->clear_regions(); - _editor->selection->clear_points (); - _editor->selection->clear_lines (); } _editor->rubberband_rect->hide(); @@ -3878,16 +3842,16 @@ NoteDrag::total_dx () const /* primary note time */ frameoffset_t const n = _region->source_beats_to_absolute_frames (_primary->note()->time ()); - /* new time of the primary note relative to the region position */ + /* new time of the primary note in session frames */ frameoffset_t st = n + dx; + framepos_t const rp = _region->region()->position (); + /* prevent the note being dragged earlier than the region's position */ - if (st < 0) { - st = 0; - } + st = max (st, rp); /* snap and return corresponding delta */ - return _region->snap_frame_to_frame (st) - n; + return _region->snap_frame_to_frame (st - rp) + rp - n; } /** @return Current total drag y change in note number */ @@ -4239,3 +4203,67 @@ PatchChangeDrag::setup_pointer_frame_offset () _pointer_frame_offset = raw_grab_frame() - _region_view->source_beats_to_absolute_frames (_patch_change->patch()->time()); } +MidiRubberbandSelectDrag::MidiRubberbandSelectDrag (Editor* e, MidiRegionView* rv) + : RubberbandSelectDrag (e, rv->get_canvas_frame ()) + , _region_view (rv) +{ + +} + +void +MidiRubberbandSelectDrag::select_things (int button_state, framepos_t x1, framepos_t x2, double y1, double y2, bool drag_in_progress) +{ + framepos_t const p = _region_view->region()->position (); + double const y = _region_view->midi_view()->y_position (); + + x1 = max ((framepos_t) 0, x1 - p); + x2 = max ((framepos_t) 0, x2 - p); + y1 = max (0.0, y1 - y); + y2 = max (0.0, y2 - y); + + _region_view->update_drag_selection ( + _editor->frame_to_pixel (x1), + _editor->frame_to_pixel (x2), + y1, + y2, + Keyboard::modifier_state_contains (button_state, Keyboard::TertiaryModifier) + ); +} + +void +MidiRubberbandSelectDrag::deselect_things () +{ + /* XXX */ +} + +EditorRubberbandSelectDrag::EditorRubberbandSelectDrag (Editor* e, ArdourCanvas::Item* i) + : RubberbandSelectDrag (e, i) +{ + +} + +void +EditorRubberbandSelectDrag::select_things (int button_state, framepos_t x1, framepos_t x2, double y1, double y2, bool drag_in_progress) +{ + if (drag_in_progress) { + /* We just want to select things at the end of the drag, not during it */ + return; + } + + Selection::Operation op = ArdourKeyboard::selection_type (button_state); + + _editor->begin_reversible_command (_("rubberband selection")); + _editor->select_all_within (x1, x2 - 1, y1, y2, _editor->track_views, op, false); + _editor->commit_reversible_command (); +} + +void +EditorRubberbandSelectDrag::deselect_things () +{ + if (!getenv("ARDOUR_SAE")) { + _editor->selection->clear_tracks(); + } + _editor->selection->clear_regions(); + _editor->selection->clear_points (); + _editor->selection->clear_lines (); +}