Fix wonky note length when create-dragging notes backwards.
[ardour.git] / gtk2_ardour / editor_drag.cc
index 55ad3da6f7696866043a17d0a0c0f401b9ac79ef..0aaec8d24d5e4e8129b1f919fd2b5bf45d668696 100644 (file)
@@ -1791,6 +1791,15 @@ void
 RegionRippleDrag::finished (GdkEvent* event, bool movement_occurred)
 {
        if (!movement_occurred) {
+               
+               /* just a click */
+
+               if (was_double_click() && !_views.empty()) {
+                       DraggingView dv = _views.front();
+                       dv.view->show_region_editor ();
+                       
+               }
+
                return;
        }
 
@@ -1958,7 +1967,10 @@ NoteResizeDrag::start_grab (GdkEvent* event, Gdk::Cursor* /*ignored*/)
                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;
        }
 }
@@ -1970,7 +1982,10 @@ NoteResizeDrag::motion (GdkEvent* /*event*/, bool /*first_move*/)
        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);
+               }
        }
 }
 
@@ -1981,7 +1996,10 @@ NoteResizeDrag::finished (GdkEvent*, bool /*movement_occurred*/)
        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);
+               }
        }
 }
 
@@ -1990,7 +2008,10 @@ NoteResizeDrag::aborted (bool)
 {
        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 ();
+               }
        }
 }
 
@@ -2574,7 +2595,7 @@ MeterMarkerDrag::motion (GdkEvent* event, bool first_move)
                _marker = new MeterMarker (
                        *_editor,
                        *_editor->meter_group,
-                       ARDOUR_UI::config()->get_canvasvar_MeterMarker(),
+                       ARDOUR_UI::config()->get_MeterMarker(),
                        name,
                        *new MeterSection (_marker->meter())
                );
@@ -2704,7 +2725,7 @@ TempoMarkerDrag::motion (GdkEvent* event, bool first_move)
                _marker = new TempoMarker (
                        *_editor,
                        *_editor->tempo_group,
-                       ARDOUR_UI::config()->get_canvasvar_TempoMarker(),
+                       ARDOUR_UI::config()->get_TempoMarker(),
                        name,
                        *new TempoSection (_marker->tempo())
                        );
@@ -4239,9 +4260,16 @@ SelectionDrag::motion (GdkEvent* event, bool first_move)
                        }
                }
                
+               //if user is selecting a range on an automation track, bail out here before we get to the grouped stuff, 
+               // because the grouped stuff will start working on tracks (routeTAVs), and end up removing this 
+               AutomationTimeAxisView *atest = dynamic_cast<AutomationTimeAxisView *>(_editor->clicked_axisview);
+               if (atest) {
+                       _editor->selection->add (atest);
+                       break; 
+               }
+               
                /* select all tracks within the rectangle that we've marked out so far */
-               TrackViewList to_be_added_to_selection;
-               TrackViewList to_be_removed_from_selection;
+               TrackViewList new_selection;
                TrackViewList& all_tracks (_editor->track_views);
 
                ArdourCanvas::Coord const top = grab_y();
@@ -4249,26 +4277,39 @@ SelectionDrag::motion (GdkEvent* event, bool first_move)
 
                if (top >= 0 && bottom >= 0) {
 
+                       //first, find the tracks that are covered in the y range selection
                        for (TrackViewList::const_iterator i = all_tracks.begin(); i != all_tracks.end(); ++i) {
-                       
                                if ((*i)->covered_by_y_range (top, bottom)) {
-                                       if (!(*i)->get_selected()) {
-                                               to_be_added_to_selection.push_back (*i);
-                                       }
-                               } else {
-                                       if ((*i)->get_selected()) {
-                                               to_be_removed_from_selection.push_back (*i);
-                                       }
+                                       new_selection.push_back (*i);
                                }
                        }
 
-                       if (!to_be_added_to_selection.empty()) {
-                               _editor->selection->add (to_be_added_to_selection);
-                       }
-                       
-                       if (!to_be_removed_from_selection.empty()) {
-                               _editor->selection->remove (to_be_removed_from_selection);
+                       //now find any tracks that are GROUPED with the tracks we selected
+                       TrackViewList grouped_add = new_selection;
+                       for (TrackViewList::const_iterator i = new_selection.begin(); i != new_selection.end(); ++i) {
+                               RouteTimeAxisView *n = dynamic_cast<RouteTimeAxisView *>(*i);
+                               if ( n && n->route()->route_group() && n->route()->route_group()->is_active() && n->route()->route_group()->enabled_property (ARDOUR::Properties::select.property_id) ) {
+                                       for (TrackViewList::const_iterator j = all_tracks.begin(); j != all_tracks.end(); ++j) {
+                                               RouteTimeAxisView *check = dynamic_cast<RouteTimeAxisView *>(*j);
+                                               if ( check && (n != check) && (check->route()->route_group() == n->route()->route_group()) )
+                                                       grouped_add.push_back (*j);
+                                       }
+                               }
                        }
+
+                       //now compare our list with the current selection, and add or remove as necessary
+                       //( NOTE: most mouse moves don't change the selection so we can't just SET it for every mouse move; it gets clunky )
+                       TrackViewList tracks_to_add;
+                       TrackViewList tracks_to_remove;
+                       for (TrackViewList::const_iterator i = grouped_add.begin(); i != grouped_add.end(); ++i)
+                               if ( !_editor->selection->tracks.contains ( *i ) )
+                                       tracks_to_add.push_back ( *i );
+                       for (TrackViewList::const_iterator i = _editor->selection->tracks.begin(); i != _editor->selection->tracks.end(); ++i)
+                               if ( !grouped_add.contains ( *i ) )
+                                       tracks_to_remove.push_back ( *i );
+                       _editor->selection->add(tracks_to_add);
+                       _editor->selection->remove(tracks_to_remove);
+
                }
        }
        break;
@@ -4416,8 +4457,8 @@ RangeMarkerBarDrag::RangeMarkerBarDrag (Editor* e, ArdourCanvas::Item* i, Operat
                                                                      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()->get_RangeDragRect());
+       _drag_rect->set_outline_color (ARDOUR_UI::config()->get_RangeDragRect());
 }
 
 void
@@ -4434,6 +4475,7 @@ RangeMarkerBarDrag::start_grab (GdkEvent* event, Gdk::Cursor *)
        }
 
        switch (_operation) {
+       case CreateSkipMarker:
        case CreateRangeMarker:
        case CreateTransportMarker:
        case CreateCDMarker:
@@ -4460,6 +4502,9 @@ RangeMarkerBarDrag::motion (GdkEvent* event, bool first_move)
        ArdourCanvas::Rectangle *crect;
 
        switch (_operation) {
+       case CreateSkipMarker:
+               crect = _editor->range_bar_drag_rect;
+               break;
        case CreateRangeMarker:
                crect = _editor->range_bar_drag_rect;
                break;
@@ -4477,7 +4522,7 @@ RangeMarkerBarDrag::motion (GdkEvent* event, bool first_move)
 
        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);
 
@@ -4533,17 +4578,24 @@ RangeMarkerBarDrag::finished (GdkEvent* event, bool movement_occurred)
                _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();
                        }
@@ -4579,7 +4631,7 @@ RangeMarkerBarDrag::finished (GdkEvent* event, bool movement_occurred)
                        /* didn't drag, but mark is already created so do
                         * nothing */
 
-               } else { /* operation == CreateRangeMarker */
+               } else { /* operation == CreateRangeMarker || CreateSkipMarker */
                        
 
                        framepos_t start;
@@ -4631,88 +4683,6 @@ RangeMarkerBarDrag::update_item (Location* location)
        _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)
@@ -4979,8 +4949,8 @@ AutomationRangeDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor)
                                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->add (p, the_list->eval (p));
-                               the_list->add (q, the_list->eval (q));
+                               the_list->editor_add (p, the_list->eval (p));
+                               the_list->editor_add (q, the_list->eval (q));
                        }
 
                        /* same thing for the end */
@@ -5005,8 +4975,8 @@ AutomationRangeDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor)
                                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->add (p, the_list->eval (p));
-                               the_list->add (q, the_list->eval (q));
+                               the_list->editor_add (p, the_list->eval (p));
+                               the_list->editor_add (q, the_list->eval (q));
                        }
                }
 
@@ -5310,12 +5280,10 @@ void
 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