#include "i18n.h"
#include "keyboard.h"
#include "audio_region_view.h"
+#include "automation_region_view.h"
#include "midi_region_view.h"
#include "ardour_ui.h"
#include "gui_thread.h"
}
_drags.clear ();
+ _editor->abort_reversible_command();
_ending = false;
}
, _pointer_frame_offset (0)
, _trackview_only (trackview_only)
, _move_threshold_passed (false)
+ , _starting_point_passed (false)
, _was_double_click (false)
, _raw_grab_frame (0)
, _grab_frame (0)
_item->ungrab ();
_item = new_item;
- if (cursor == 0) {
- _item->grab ();
+ if (!_cursor_ctx) {
+ _cursor_ctx = CursorContext::create (*_editor, cursor);
} else {
- _item->grab ();
+ _cursor_ctx->change (cursor);
}
+
+ _item->grab ();
}
void
_last_pointer_y = _grab_y;
- if (cursor == 0) {
- _item->grab ();
- } else {
+ _item->grab ();
+
+ if (!_editor->cursors()->is_invalid (cursor)) {
/* CAIROCANVAS need a variant here that passes *cursor */
- _item->grab ();
- _editor->push_canvas_cursor (cursor);
+ _cursor_ctx = CursorContext::create (*_editor, cursor);
}
if (_editor->session() && _editor->session()->transport_rolling()) {
finished (event, _move_threshold_passed);
_editor->verbose_cursor()->hide ();
- _editor->pop_canvas_cursor ();
+ _cursor_ctx.reset();
return _move_threshold_passed;
}
return adjusted_frame (_drags->current_pointer_frame (), event, snap);
}
+double
+Drag::current_pointer_x() const
+{
+ return _drags->current_pointer_x ();
+}
+
double
Drag::current_pointer_y () const
{
{
/* check to see if we have moved in any way that matters since the last motion event */
if (_move_threshold_passed &&
- (!x_movement_matters() || _last_pointer_frame == adjusted_current_frame (event)) &&
+ (!x_movement_matters() || _last_pointer_x == current_pointer_x ()) &&
(!y_movement_matters() || _last_pointer_y == current_pointer_y ()) ) {
return false;
}
bool const old_move_threshold_passed = _move_threshold_passed;
- if (!from_autoscroll && !_move_threshold_passed) {
+ if (!_move_threshold_passed) {
bool const xp = (::llabs (_drags->current_pointer_frame () - _raw_grab_frame) >= threshold.first);
bool const yp = (::fabs ((current_pointer_y () - _grab_y)) >= threshold.second);
}
if (!_editor->autoscroll_active() || from_autoscroll) {
- motion (event, _move_threshold_passed != old_move_threshold_passed);
+
+ bool first_move = (_move_threshold_passed != old_move_threshold_passed) ||
+ from_autoscroll;
+ motion (event, first_move && !_starting_point_passed);
+
+ if (first_move && !_starting_point_passed) {
+ _starting_point_passed = true;
+ }
_last_pointer_x = _drags->current_pointer_x ();
_last_pointer_y = current_pointer_y ();
for (list<DraggingView>::iterator i = _views.begin(); i != _views.end(); ++i) {
RegionView* rv = i->view;
+ double y_delta;
+
+ y_delta = 0;
if (rv->region()->locked() || rv->region()->video_locked()) {
continue;
/* move the item so that it continues to appear at the
same location now that its parent has changed.
*/
- rvg->move (rv_canvas_offset - dmg_canvas_offset);
+ rvg->move (rv_canvas_offset - dmg_canvas_offset);
}
/* If we have moved tracks, we'll fudge the layer delta so that the
} else {
track_index = _time_axis_views.size() - 1 + delta_time_axis_view;
}
-
+
if (track_index < 0 || track_index >= (int) _time_axis_views.size()) {
continue;
}
* equivalent coordinate space as the trackview
* we are now dragging over.
*/
+
+ y_delta = track_origin.y - rv->get_canvas_group()->canvas_origin().y;
- /* Now move the region view */
- rv->move (x_delta, track_origin.y - rv->get_canvas_group()->canvas_origin().y);
}
+
+
} else {
/* Only move the region into the empty dropzone at the bottom if the pointer
last_track_bottom_edge = 0;
}
- rv->move (x_delta, last_track_bottom_edge - rv->get_canvas_group()->canvas_origin().y);
+ y_delta = last_track_bottom_edge - rv->get_canvas_group()->canvas_origin().y;
i->time_axis_view = -1;
}
}
+ /* Now move the region view */
+ rv->move (x_delta, y_delta);
+
} /* foreach region */
_total_x_delta += x_delta;
{
if (_copy && first_move) {
+ if (_x_constrained) {
+ _editor->begin_reversible_command (Operations::fixed_time_region_copy);
+ } else {
+ _editor->begin_reversible_command (Operations::region_copy);
+ }
+
/* duplicate the regionview(s) and region(s) */
list<DraggingView> new_regionviews;
swap_grab (new_regionviews.front().view->get_canvas_group (), 0, event ? event->motion.time : 0);
}
+
+ } else if (!_copy && first_move) {
+
+ if (_x_constrained) {
+ _editor->begin_reversible_command (_("fixed time region drag"));
+ } else {
+ _editor->begin_reversible_command (Operations::region_drag);
+ }
}
RegionMotionDrag::motion (event, first_move);
return;
}
- if (_x_constrained) {
- _editor->begin_reversible_command (Operations::fixed_time_region_copy);
- } else {
- _editor->begin_reversible_command (Operations::region_copy);
- }
+ typedef map<boost::shared_ptr<Playlist>, RouteTimeAxisView*> PlaylistMapping;
+ PlaylistMapping playlist_mapping;
+
+ typedef map<boost::shared_ptr<Playlist>, RouteTimeAxisView*> PlaylistMapping;
+ PlaylistMapping playlist_mapping;
/* insert the regions into their new playlists */
for (list<DraggingView>::const_iterator i = _views.begin(); i != _views.end();) {
} else {
where = i->view->region()->position();
}
-
+
if (i->time_axis_view < 0) {
- if (!new_time_axis_view) {
+ /* dragged to drop zone */
+
+ PlaylistMapping::iterator pm;
+
+ if ((pm = playlist_mapping.find (i->view->region()->playlist())) == playlist_mapping.end()) {
+ /* first region from this original playlist: create a new track */
new_time_axis_view = create_destination_time_axis (i->view->region(), i->initial_time_axis_view);
+ playlist_mapping.insert (make_pair (i->view->region()->playlist(), new_time_axis_view));
+ dest_rtv = new_time_axis_view;
+ } else {
+ /* we already created a new track for regions from this playlist, use it */
+ dest_rtv = pm->second;
}
- dest_rtv = new_time_axis_view;
} else {
+ /* destination time axis view is the one we dragged to */
dest_rtv = dynamic_cast<RouteTimeAxisView*> (_time_axis_views[i->time_axis_view]);
}
return;
}
- if (_x_constrained) {
- _editor->begin_reversible_command (_("fixed time region drag"));
- } else {
- _editor->begin_reversible_command (Operations::region_drag);
- }
+ typedef map<boost::shared_ptr<Playlist>, RouteTimeAxisView*> PlaylistMapping;
+ PlaylistMapping playlist_mapping;
+
+ typedef map<boost::shared_ptr<Playlist>, RouteTimeAxisView*> PlaylistMapping;
+ PlaylistMapping playlist_mapping;
for (list<DraggingView>::const_iterator i = _views.begin(); i != _views.end(); ) {
}
if (i->time_axis_view < 0) {
- if (!new_time_axis_view) {
- new_time_axis_view = create_destination_time_axis (rv->region(), i->initial_time_axis_view);
+ /* dragged to drop zone */
+
+ PlaylistMapping::iterator pm;
+
+ if ((pm = playlist_mapping.find (i->view->region()->playlist())) == playlist_mapping.end()) {
+ /* first region from this original playlist: create a new track */
+ new_time_axis_view = create_destination_time_axis (i->view->region(), i->initial_time_axis_view);
+ playlist_mapping.insert (make_pair (i->view->region()->playlist(), new_time_axis_view));
+ dest_rtv = new_time_axis_view;
+ } else {
+ /* we already created a new track for regions from this playlist, use it */
+ dest_rtv = pm->second;
}
- dest_rtv = new_time_axis_view;
+
} else {
+ /* destination time axis view is the one we dragged to */
dest_rtv = dynamic_cast<RouteTimeAxisView*> (_time_axis_views[i->time_axis_view]);
- }
-
+ }
+
assert (dest_rtv);
double const dest_layer = i->layer;
{
if (_copy) {
- for (list<DraggingView>::const_iterator i = _views.begin(); i != _views.end(); ++i) {
+ for (list<DraggingView>::const_iterator i = _views.begin(); i != _views.end();) {
+ list<DraggingView>::const_iterator next = i;
+ ++next;
delete i->view;
+ i = next;
}
_views.clear ();
if (x_fraction > 0.0 && x_fraction < 0.25) {
cursor = _editor->cursors()->left_side_trim;
+ at_front = true;
} else {
cursor = _editor->cursors()->right_side_trim;
+ at_front = false;
}
Drag::start_grab (event, cursor);
region = &cnote->region_view();
- double const region_start = region->get_position_pixels();
- double const middle_point = region_start + cnote->x0() + (cnote->x1() - cnote->x0()) / 2.0L;
-
- if (grab_x() <= middle_point) {
- cursor = _editor->cursors()->left_side_trim;
- at_front = true;
- } else {
- cursor = _editor->cursors()->right_side_trim;
- at_front = false;
- }
-
_item->grab ();
if (event->motion.state & Keyboard::PrimaryModifier) {
*/
region->note_selected (cnote, cnote->selected ());
+ _editor->begin_reversible_command (_("resize notes"));
+
for (MidiRegionSelection::iterator r = ms.begin(); r != ms.end(); ) {
MidiRegionSelection::iterator next;
next = r;
++next;
- (*r)->begin_resizing (at_front);
+ MidiRegionView* mrv = dynamic_cast<MidiRegionView*>(*r);
+ if (mrv) {
+ mrv->begin_resizing (at_front);
+ }
r = next;
}
}
for (MidiRegionSelection::iterator r = ms.begin(); r != ms.end(); ++r) {
NoteBase* nb = reinterpret_cast<NoteBase*> (_item->get_data ("notebase"));
assert (nb);
- (*r)->update_resizing (nb, at_front, _drags->current_pointer_x() - grab_x(), relative);
+ MidiRegionView* mrv = dynamic_cast<MidiRegionView*>(*r);
+ if (mrv) {
+ mrv->update_resizing (nb, at_front, _drags->current_pointer_x() - grab_x(), relative);
+ }
}
}
for (MidiRegionSelection::iterator r = ms.begin(); r != ms.end(); ++r) {
NoteBase* nb = reinterpret_cast<NoteBase*> (_item->get_data ("notebase"));
assert (nb);
- (*r)->commit_resizing (nb, at_front, _drags->current_pointer_x() - grab_x(), relative);
+ MidiRegionView* mrv = dynamic_cast<MidiRegionView*>(*r);
+ if (mrv) {
+ mrv->commit_resizing (nb, at_front, _drags->current_pointer_x() - grab_x(), relative);
+ }
}
+
+ _editor->commit_reversible_command ();
}
void
{
MidiRegionSelection& ms (_editor->get_selection().midi_regions);
for (MidiRegionSelection::iterator r = ms.begin(); r != ms.end(); ++r) {
- (*r)->abort_resizing ();
+ MidiRegionView* mrv = dynamic_cast<MidiRegionView*>(*r);
+ if (mrv) {
+ mrv->abort_resizing ();
+ }
}
}
_marker = new MeterMarker (
*_editor,
*_editor->meter_group,
- ARDOUR_UI::config()->get_canvasvar_MeterMarker(),
+ ARDOUR_UI::config()->color ("meter marker"),
name,
*new MeterSection (_marker->meter())
);
}
framepos_t const pf = adjusted_current_frame (event);
+
_marker->set_position (pf);
show_verbose_cursor_time (pf);
}
_marker = new TempoMarker (
*_editor,
*_editor->tempo_group,
- ARDOUR_UI::config()->get_canvasvar_TempoMarker(),
+ ARDOUR_UI::config()->color ("tempo marker"),
name,
*new TempoSection (_marker->tempo())
);
motion (event, false);
TempoMap& map (_editor->session()->tempo_map());
- framepos_t beat_time = map.round_to_beat (last_pointer_frame(), 0);
+ framepos_t beat_time = map.round_to_beat (last_pointer_frame(), RoundNearest);
Timecode::BBT_Time when;
map.bbt_time (beat_time, when);
} else if (new_start < copy_location->end()) {
copy_location->set_start (new_start);
} else if (newframe > 0) {
- _editor->snap_to (next, 1, true);
+ _editor->snap_to (next, RoundUpAlways, true);
copy_location->set_end (next);
copy_location->set_start (newframe);
}
} else if (new_end > copy_location->start()) {
copy_location->set_end (new_end);
} else if (newframe > 0) {
- _editor->snap_to (next, -1, true);
+ _editor->snap_to (next, RoundDownAlways, true);
copy_location->set_start (next);
copy_location->set_end (newframe);
}
}
void
-MarkerDrag::aborted (bool)
+MarkerDrag::aborted (bool movement_occured)
{
- /* XXX: TODO */
+ if (!movement_occured) {
+ return;
+ }
+
+ for (CopiedLocationInfo::iterator x = _copied_locations.begin(); x != _copied_locations.end(); ++x) {
+
+ /* move all markers to their original location */
+
+
+ for (vector<Marker*>::iterator m = x->markers.begin(); m != x->markers.end(); ++m) {
+
+ bool is_start;
+ Location * location = _editor->find_location_from_marker (*m, is_start);
+
+ if (location) {
+ (*m)->set_position (is_start ? location->start() : location->end());
+ }
+ }
+ }
}
void
}
_point->line().end_drag (_pushing, _final_index);
- _editor->session()->commit_reversible_command ();
+ _editor->commit_reversible_command ();
}
void
bool
ControlPointDrag::active (Editing::MouseMode m)
{
- if (m == Editing::MouseGain) {
- /* always active in mouse gain */
+ if (m == Editing::MouseDraw) {
+ /* always active in mouse draw */
return true;
}
}
}
- _editor->session()->commit_reversible_command ();
+ _editor->commit_reversible_command ();
}
void
RubberbandSelectDrag::start_grab (GdkEvent* event, Gdk::Cursor *)
{
Drag::start_grab (event);
- show_verbose_cursor_time (adjusted_current_frame (event));
+ show_verbose_cursor_time (adjusted_current_frame (event, ARDOUR_UI::config()->get_rubberbanding_snaps_to_grid()));
}
void
double y1;
double y2;
- framepos_t const pf = adjusted_current_frame (event, Config->get_rubberbanding_snaps_to_grid ());
+ framepos_t const pf = adjusted_current_frame (event, ARDOUR_UI::config()->get_rubberbanding_snaps_to_grid());
framepos_t grab = grab_frame ();
- if (Config->get_rubberbanding_snaps_to_grid ()) {
+ if (ARDOUR_UI::config()->get_rubberbanding_snaps_to_grid ()) {
_editor->snap_to_with_modifier (grab, event);
+ } else {
+ grab = raw_grab_frame ();
}
/* base start and end on initial click position */
{
framepos_t x1;
framepos_t x2;
+ framepos_t grab = grab_frame ();
+ framepos_t lpf = last_pointer_frame ();
+
+ if (!ARDOUR_UI::config()->get_rubberbanding_snaps_to_grid ()) {
+ grab = raw_grab_frame ();
+ lpf = _editor->pixel_to_sample_from_event (last_pointer_x());
+ }
- if (grab_frame() < last_pointer_frame()) {
- x1 = grab_frame ();
- x2 = last_pointer_frame ();
+ if (grab < lpf) {
+ x1 = grab;
+ x2 = lpf;
} else {
- x2 = grab_frame ();
- x1 = last_pointer_frame ();
+ x2 = grab;
+ x1 = lpf;
}
double y1;
if ((mtv = dynamic_cast<MidiTimeAxisView*>(_editor->clicked_axisview)) != 0) {
/* MIDI track */
- if (_editor->selection->empty()) {
+ if (_editor->selection->empty() && _editor->mouse_mode == MouseDraw) {
/* nothing selected */
add_midi_region (mtv);
do_deselect = false;
: Drag (e, i)
, _operation (o)
, _add (false)
- , _extend (false)
, _original_pointer_time_axis (-1)
- , _last_pointer_time_axis (-1)
, _time_selection_at_start (!_editor->get_selection().time.empty())
{
DEBUG_TRACE (DEBUG::Drags, "New SelectionDrag\n");
return;
}
- Gdk::Cursor* cursor = 0;
+ Gdk::Cursor* cursor = MouseCursors::invalid_cursor();
switch (_operation) {
case CreateSelection:
if (first_move) {
grab = adjusted_current_frame (event, false);
if (grab < pending_position) {
- _editor->snap_to (grab, -1);
+ _editor->snap_to (grab, RoundDownMaybe);
} else {
- _editor->snap_to (grab, 1);
+ _editor->snap_to (grab, RoundUpMaybe);
}
}
{
Session* s = _editor->session();
+ _editor->begin_reversible_selection_op (_("Change Time Selection"));
if (movement_occurred) {
motion (event, false);
/* XXX this is not object-oriented programming at all. ick */
if ( s->get_play_range() && s->transport_rolling() ) {
s->request_play_range (&_editor->selection->time, true);
} else {
- if (Config->get_follow_edits() && !s->transport_rolling()) {
+ if (ARDOUR_UI::config()->get_follow_edits() && !s->transport_rolling()) {
if (_operation == SelectionEndTrim)
_editor->maybe_locate_with_edit_preroll( _editor->get_selection().time.end_frame());
else
_editor->stop_canvas_autoscroll ();
_editor->clicked_selection = 0;
+ _editor->commit_reversible_selection_op ();
}
void
physical_screen_height (_editor->get_window())));
_drag_rect->hide ();
- _drag_rect->set_fill_color (ARDOUR_UI::config()->get_canvasvar_RangeDragRect());
- _drag_rect->set_outline_color (ARDOUR_UI::config()->get_canvasvar_RangeDragRect());
+ _drag_rect->set_fill_color (ARDOUR_UI::config()->color ("range drag rect"));
+ _drag_rect->set_outline_color (ARDOUR_UI::config()->color ("range drag rect"));
+}
+
+RangeMarkerBarDrag::~RangeMarkerBarDrag()
+{
+ /* normal canvas items will be cleaned up when their parent group is deleted. But
+ this item is created as the child of a long-lived parent group, and so we
+ need to explicitly delete it.
+ */
+ delete _drag_rect;
}
void
return;
}
- Gdk::Cursor* cursor = 0;
+ Gdk::Cursor* cursor = MouseCursors::invalid_cursor();
if (!_editor->temp_location) {
_editor->temp_location = new Location (*_editor->session());
}
switch (_operation) {
+ case CreateSkipMarker:
case CreateRangeMarker:
case CreateTransportMarker:
case CreateCDMarker:
ArdourCanvas::Rectangle *crect;
switch (_operation) {
+ case CreateSkipMarker:
+ crect = _editor->range_bar_drag_rect;
+ break;
case CreateRangeMarker:
crect = _editor->range_bar_drag_rect;
break;
framepos_t const pf = adjusted_current_frame (event);
- if (_operation == CreateRangeMarker || _operation == CreateTransportMarker || _operation == CreateCDMarker) {
+ if (_operation == CreateSkipMarker || _operation == CreateRangeMarker || _operation == CreateTransportMarker || _operation == CreateCDMarker) {
framepos_t grab = grab_frame ();
_editor->snap_to (grab);
_drag_rect->hide();
switch (_operation) {
+ case CreateSkipMarker:
case CreateRangeMarker:
case CreateCDMarker:
{
- _editor->begin_reversible_command (_("new range marker"));
XMLNode &before = _editor->session()->locations()->get_state();
- _editor->session()->locations()->next_available_name(rangename,"unnamed");
- if (_operation == CreateCDMarker) {
+ if (_operation == CreateSkipMarker) {
+ _editor->begin_reversible_command (_("new skip marker"));
+ _editor->session()->locations()->next_available_name(rangename,_("skip"));
+ flags = Location::IsRangeMarker | Location::IsSkip;
+ _editor->range_bar_drag_rect->hide();
+ } else if (_operation == CreateCDMarker) {
+ _editor->session()->locations()->next_available_name(rangename, _("CD"));
+ _editor->begin_reversible_command (_("new CD marker"));
flags = Location::IsRangeMarker | Location::IsCDMarker;
_editor->cd_marker_bar_drag_rect->hide();
- }
- else {
+ } else {
+ _editor->begin_reversible_command (_("new skip marker"));
+ _editor->session()->locations()->next_available_name(rangename, _("unnamed"));
flags = Location::IsRangeMarker;
_editor->range_bar_drag_rect->hide();
}
/* didn't drag, but mark is already created so do
* nothing */
- } else { /* operation == CreateRangeMarker */
+ } else { /* operation == CreateRangeMarker || CreateSkipMarker */
framepos_t start;
}
void
-RangeMarkerBarDrag::aborted (bool)
+RangeMarkerBarDrag::aborted (bool movement_occured)
{
- /* XXX: TODO */
+ if (movement_occured) {
+ _drag_rect->hide ();
+ }
}
void
_drag_rect->set_x1 (x2);
}
-MouseZoomDrag::MouseZoomDrag (Editor* e, ArdourCanvas::Item* i)
- : Drag (e, i)
- , _zoom_out (false)
-{
- DEBUG_TRACE (DEBUG::Drags, "New MouseZoomDrag\n");
-}
-
-void
-MouseZoomDrag::start_grab (GdkEvent* event, Gdk::Cursor *)
-{
- if (Keyboard::the_keyboard().key_is_down (GDK_Control_L)) {
- Drag::start_grab (event, _editor->cursors()->zoom_out);
- _zoom_out = true;
- } else {
- Drag::start_grab (event, _editor->cursors()->zoom_in);
- _zoom_out = false;
- }
-
- show_verbose_cursor_time (adjusted_current_frame (event));
-}
-
-void
-MouseZoomDrag::motion (GdkEvent* event, bool first_move)
-{
- framepos_t start;
- framepos_t end;
-
- framepos_t const pf = adjusted_current_frame (event);
-
- framepos_t grab = grab_frame ();
- _editor->snap_to_with_modifier (grab, event);
-
- /* base start and end on initial click position */
- if (pf < grab) {
- start = pf;
- end = grab;
- } else {
- end = pf;
- start = grab;
- }
-
- if (start != end) {
-
- if (first_move) {
- _editor->zoom_rect->show();
- _editor->zoom_rect->raise_to_top();
- }
-
- _editor->reposition_zoom_rect(start, end);
-
- show_verbose_cursor_time (pf);
- }
-}
-
-void
-MouseZoomDrag::finished (GdkEvent* event, bool movement_occurred)
-{
- if (movement_occurred) {
- motion (event, false);
-
- if (grab_frame() < last_pointer_frame()) {
- _editor->temporal_zoom_by_frame (grab_frame(), last_pointer_frame());
- } else {
- _editor->temporal_zoom_by_frame (last_pointer_frame(), grab_frame());
- }
- } else {
- if (Keyboard::the_keyboard().key_is_down (GDK_Shift_L)) {
- _editor->tav_zoom_step (_zoom_out);
- } else {
- _editor->temporal_zoom_to_frame (_zoom_out, grab_frame());
- }
- }
-
- _editor->zoom_rect->hide();
-}
-
-void
-MouseZoomDrag::aborted (bool)
-{
- _editor->zoom_rect->hide ();
-}
-
NoteDrag::NoteDrag (Editor* e, ArdourCanvas::Item* i)
: Drag (e, i)
, _cumulative_dx (0)
} else {
_region->unique_select (_primary);
}
+
+ _editor->begin_reversible_selection_op(_("Select Note Press"));
+ _editor->commit_reversible_selection_op();
}
}
}
{
if (!moved) {
/* no motion - select note */
-
+
if (_editor->current_mouse_mode() == Editing::MouseObject ||
_editor->current_mouse_mode() == Editing::MouseDraw) {
-
+
+ bool changed = false;
+
if (_was_selected) {
bool add = Keyboard::modifier_state_equals (ev->button.state, Keyboard::PrimaryModifier);
if (add) {
_region->note_deselected (_primary);
+ changed = true;
}
} else {
bool extend = Keyboard::modifier_state_equals (ev->button.state, Keyboard::TertiaryModifier);
if (!extend && !add && _region->selection_size() > 1) {
_region->unique_select (_primary);
+ changed = true;
} else if (extend) {
_region->note_selected (_primary, true, true);
+ changed = true;
} else {
/* it was added during button press */
}
}
+
+ if (changed) {
+ _editor->begin_reversible_selection_op(_("Select Note Release"));
+ _editor->commit_reversible_selection_op();
+ }
}
} else {
_region->note_dropped (_primary, total_dx(), total_dy());
AutomationRangeDrag::AutomationRangeDrag (Editor* editor, AutomationTimeAxisView* atv, list<AudioRange> const & r)
: Drag (editor, atv->base_item ())
, _ranges (r)
+ , _y_origin (atv->y_position())
, _nothing_to_drag (false)
{
DEBUG_TRACE (DEBUG::Drags, "New AutomationRangeDrag\n");
- y_origin = atv->y_position();
setup (atv->lines ());
}
-/** Make an AutomationRangeDrag for region gain lines */
-AutomationRangeDrag::AutomationRangeDrag (Editor* editor, AudioRegionView* rv, list<AudioRange> const & r)
+/** Make an AutomationRangeDrag for region gain lines or MIDI controller regions */
+AutomationRangeDrag::AutomationRangeDrag (Editor* editor, RegionView* rv, list<AudioRange> const & r)
: Drag (editor, rv->get_canvas_group ())
, _ranges (r)
+ , _y_origin (rv->get_time_axis_view().y_position())
, _nothing_to_drag (false)
+ , _integral (false)
{
DEBUG_TRACE (DEBUG::Drags, "New AutomationRangeDrag\n");
list<boost::shared_ptr<AutomationLine> > lines;
- lines.push_back (rv->get_gain_line ());
- y_origin = rv->get_time_axis_view().y_position();
+
+ AudioRegionView* audio_view;
+ AutomationRegionView* automation_view;
+ if ((audio_view = dynamic_cast<AudioRegionView*>(rv))) {
+ lines.push_back (audio_view->get_gain_line ());
+ } else if ((automation_view = dynamic_cast<AutomationRegionView*>(rv))) {
+ lines.push_back (automation_view->line ());
+ _integral = true;
+ } else {
+ error << _("Automation range drag created for invalid region type") << endmsg;
+ }
+
setup (lines);
}
double
AutomationRangeDrag::y_fraction (boost::shared_ptr<AutomationLine> line, double global_y) const
{
- return 1.0 - ((global_y - y_origin) / line->height());
+ return 1.0 - ((global_y - _y_origin) / line->height());
+}
+
+double
+AutomationRangeDrag::value (boost::shared_ptr<AutomationList> list, double x) const
+{
+ const double v = list->eval(x);
+ return _integral ? rint(v) : v;
}
void
double const p = j->line->time_converter().from (i->start - j->line->time_converter().origin_b ());
double const q = j->line->time_converter().from (a - j->line->time_converter().origin_b ());
- the_list->editor_add (p, the_list->eval (p));
- the_list->editor_add (q, the_list->eval (q));
+ the_list->editor_add (p, value (the_list, p));
+ the_list->editor_add (q, value (the_list, q));
}
/* same thing for the end */
double const p = j->line->time_converter().from (b - j->line->time_converter().origin_b ());
double const q = j->line->time_converter().from (i->end - j->line->time_converter().origin_b ());
- the_list->editor_add (p, the_list->eval (p));
- the_list->editor_add (q, the_list->eval (q));
+ the_list->editor_add (p, value (the_list, p));
+ the_list->editor_add (q, value (the_list, q));
}
}
i->line->end_drag (false, 0);
}
- _editor->session()->commit_reversible_command ();
+ _editor->commit_reversible_command ();
}
void
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->sample_to_pixel (x1),
- _editor->sample_to_pixel (x2),
- y1,
- y2,
- Keyboard::modifier_state_contains (button_state, Keyboard::TertiaryModifier)
- );
+ x1, x2, y1, y2,
+ Keyboard::modifier_state_contains (button_state, Keyboard::TertiaryModifier));
}
void
}
Selection::Operation op = ArdourKeyboard::selection_type (button_state);
-
- _editor->begin_reversible_command (_("rubberband selection"));
+
+ _editor->begin_reversible_selection_op (_("rubberband selection"));
+
_editor->select_all_within (x1, x2 - 1, y1, y2, _editor->track_views, op, false);
- _editor->commit_reversible_command ();
+
+ _editor->commit_reversible_selection_op ();
}
void
EditorRubberbandSelectDrag::deselect_things ()
{
- if (!getenv("ARDOUR_SAE")) {
- _editor->selection->clear_tracks();
- }
+ _editor->begin_reversible_selection_op (_("Clear Selection (rubberband)"));
+
+ _editor->selection->clear_tracks();
_editor->selection->clear_regions();
_editor->selection->clear_points ();
_editor->selection->clear_lines ();
+ _editor->selection->clear_midi_notes ();
+
+ _editor->commit_reversible_selection_op();
}
NoteCreateDrag::NoteCreateDrag (Editor* e, ArdourCanvas::Item* i, MidiRegionView* rv)
, _region_view (rv)
, _drag_rect (0)
{
-
+ _note[0] = _note[1] = 0;
}
NoteCreateDrag::~NoteCreateDrag ()
NoteCreateDrag::grid_frames (framepos_t t) const
{
bool success;
- Evoral::MusicalTime grid_beats = _editor->get_grid_type_as_beats (success, t);
+ Evoral::Beats grid_beats = _editor->get_grid_type_as_beats (success, t);
if (!success) {
- grid_beats = 1;
+ grid_beats = Evoral::Beats(1);
}
return _region_view->region_beats_to_region_frames (grid_beats);
}
_note[0] = adjusted_frame (pf, event) - _region_view->region()->position ();
+ _note[1] = _note[0];
MidiStreamView* sv = _region_view->midi_stream_view ();
double const x = _editor->sample_to_pixel (_note[0]);
NoteCreateDrag::motion (GdkEvent* event, bool)
{
_note[1] = max ((framepos_t)0, adjusted_current_frame (event) - _region_view->region()->position ());
- double const x = _editor->sample_to_pixel (_note[1]);
- if (_note[1] > _note[0]) {
- _drag_rect->set_x1 (x);
- } else {
- _drag_rect->set_x0 (x);
- }
+ double const x0 = _editor->sample_to_pixel (_note[0]);
+ double const x1 = _editor->sample_to_pixel (_note[1]);
+ _drag_rect->set_x0 (std::min(x0, x1));
+ _drag_rect->set_x1 (std::max(x0, x1));
}
void
framecnt_t length = (framecnt_t) fabs ((double)(_note[0] - _note[1]));
framecnt_t const g = grid_frames (start);
- double const one_tick = 1 / Timecode::BBT_Time::ticks_per_beat;
+ Evoral::Beats const one_tick = Evoral::Beats::ticks(1);
if (_editor->snap_mode() == SnapNormal && length < g) {
- length = g - one_tick;
+ length = g;
}
- double const length_beats = max (one_tick, _region_view->region_frames_to_region_beats (length));
+ Evoral::Beats length_beats = max (
+ one_tick, _region_view->region_frames_to_region_beats (length) - one_tick);
_region_view->create_note_at (start, _drag_rect->y0(), length_beats, false);
}
CrossfadeEdgeDrag::aborted (bool)
{
if (start) {
- arv->redraw_start_xfade ();
+ // arv->redraw_start_xfade ();
} else {
- arv->redraw_end_xfade ();
+ // arv->redraw_end_xfade ();
}
}