Don't use pointer_frame_offset for playhead cursor drags as it seems more intuitive...
[ardour.git] / gtk2_ardour / editor_drag.cc
index 03b9d576425b12ecdd96ddf630ebd6866a364007..8654cacdd81fc0313fa8eafdb3d35089f1740250 100644 (file)
@@ -145,21 +145,25 @@ Drag::end_grab (GdkEvent* event)
 
        _editor->hide_verbose_canvas_cursor();
 
-       update_selection ();
-       
        _ending = false;
 
        return _had_movement;
 }
 
 nframes64_t
-Drag::adjusted_current_frame () const
+Drag::adjusted_current_frame (GdkEvent* event) const
 {
+       nframes64_t pos = 0;
+       
        if (_current_pointer_frame > _pointer_frame_offset) {
-               return _current_pointer_frame - _pointer_frame_offset;
+               pos = _current_pointer_frame - _pointer_frame_offset;
        }
 
-       return 0;
+       if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) {
+               _editor->snap_to (pos);
+       }
+       
+       return pos;
 }
 
 bool
@@ -201,7 +205,7 @@ Drag::motion_handler (GdkEvent* event, bool from_autoscroll)
 
                if (event->motion.state & Gdk::BUTTON1_MASK || event->motion.state & Gdk::BUTTON2_MASK) {
                        if (!from_autoscroll) {
-                               _editor->maybe_autoscroll (&event->motion);
+                               _editor->maybe_autoscroll (&event->motion, allow_vertical_autoscroll ());
                        }
 
                        motion (event, _had_movement != old_had_movement);
@@ -247,14 +251,6 @@ RegionDrag::region_going_away (RegionView* v)
        _views.remove (v);
 }
 
-void
-RegionDrag::update_selection ()
-{
-       list<Selectable*> s;
-       copy (_views.begin(), _views.end(), back_inserter (s));
-       _editor->selection->set (s);
-}
-
 RegionMotionDrag::RegionMotionDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list<RegionView*> const & v, bool b)
        : RegionDrag (e, i, p, v),
          _dest_trackview (0),
@@ -724,11 +720,9 @@ RegionMoveDrag::motion (GdkEvent* event, bool first_move)
 }
 
 void
-RegionMoveDrag::finished (GdkEvent* event, bool movement_occurred)
+RegionMoveDrag::finished (GdkEvent* /*event*/, bool movement_occurred)
 {
-       bool nocommit = true;
        vector<RegionView*> copies;
-       RouteTimeAxisView* source_tv;
        boost::shared_ptr<Diskstream> ds;
        boost::shared_ptr<Playlist> from_playlist;
        list<RegionView*> new_views;
@@ -739,16 +733,14 @@ RegionMoveDrag::finished (GdkEvent* event, bool movement_occurred)
        pair<PlaylistSet::iterator,bool> insert_result, frozen_insert_result;
        nframes64_t drag_delta;
        bool changed_tracks, changed_position;
-       pair<TimeAxisView*, int> tvp;
        map<RegionView*, RouteTimeAxisView*> final;
+       RouteTimeAxisView* source_tv;
 
        if (!movement_occurred) {
                /* just a click */
-               goto out;
+               return;
        }
 
-       nocommit = false;
-
        if (Config->get_edit_mode() == Splice && !_editor->pre_drag_region_selection.empty()) {
                _editor->selection->set (_editor->pre_drag_region_selection);
                _editor->pre_drag_region_selection.clear ();
@@ -793,7 +785,7 @@ RegionMoveDrag::finished (GdkEvent* event, bool movement_occurred)
 
        drag_delta = _primary->region()->position() - _last_frame_position;
 
-       _editor->track_canvas->update_now ();
+       _editor->update_canvas_now ();
 
        /* make a list of where each region ended up */
        final = find_time_axis_views ();
@@ -896,10 +888,14 @@ RegionMoveDrag::finished (GdkEvent* event, bool movement_occurred)
                        /* get the playlist where this drag started. we can't use rv->region()->playlist()
                           because we may have copied the region and it has not been attached to a playlist.
                        */
+                       
+                       source_tv = dynamic_cast<RouteTimeAxisView*> (&rv->get_time_axis_view());
+                       ds = source_tv->get_diskstream();
+                       from_playlist = ds->playlist();
 
-                       assert ((source_tv = dynamic_cast<RouteTimeAxisView*> (&rv->get_time_axis_view())));
-                       assert ((ds = source_tv->get_diskstream()));
-                       assert ((from_playlist = ds->playlist()));
+                       assert (source_tv);
+                       assert (ds);
+                       assert (from_playlist);
 
                        /* moved to a different audio track, without copying */
 
@@ -971,13 +967,11 @@ RegionMoveDrag::finished (GdkEvent* event, bool movement_occurred)
        }
                        
   out:
-       if (!nocommit) {
-               for (set<boost::shared_ptr<Playlist> >::iterator p = modified_playlists.begin(); p != modified_playlists.end(); ++p) {
-                       _editor->session->add_command (new MementoCommand<Playlist>(*(*p), 0, &(*p)->get_state()));     
-               }
-
-               _editor->commit_reversible_command ();
+       for (set<boost::shared_ptr<Playlist> >::iterator p = modified_playlists.begin(); p != modified_playlists.end(); ++p) {
+               _editor->session->add_command (new MementoCommand<Playlist>(*(*p), 0, &(*p)->get_state()));     
        }
+       
+       _editor->commit_reversible_command ();
 
        for (vector<RegionView*>::iterator x = copies.begin(); x != copies.end(); ++x) {
                delete *x;
@@ -1061,7 +1055,7 @@ RegionMotionDrag::copy_regions (GdkEvent* event)
           ..only if the mouse is in rapid motion at the time of the grab. 
           something to do with regionview creation raking so long?
        */
-       _editor->track_canvas->update_now();
+       _editor->update_canvas_now();
 }
 
 bool
@@ -1248,9 +1242,9 @@ RegionMotionDrag::find_time_axis_views ()
 
 
 void
-RegionInsertDrag::finished (GdkEvent* event, bool movement_occurred)
+RegionInsertDrag::finished (GdkEvent* /*event*/, bool /*movement_occurred*/)
 {
-       _editor->track_canvas->update_now ();
+       _editor->update_canvas_now ();
 
        map<RegionView*, RouteTimeAxisView*> final = find_time_axis_views ();
        
@@ -1285,7 +1279,7 @@ struct RegionSelectionByPosition {
 };
 
 void
-RegionSpliceDrag::motion (GdkEvent* event, bool)
+RegionSpliceDrag::motion (GdkEvent* /*event*/, bool)
 {
        RouteTimeAxisView* tv;
        layer_t layer;
@@ -1343,7 +1337,7 @@ RegionSpliceDrag::motion (GdkEvent* event, bool)
 }
 
 void
-RegionSpliceDrag::finished (GdkEvent* event, bool)
+RegionSpliceDrag::finished (GdkEvent* /*event*/, bool)
 {
        
 }
@@ -1366,7 +1360,7 @@ RegionCreateDrag::start_grab (GdkEvent* event, Gdk::Cursor *)
 
 
 void
-RegionCreateDrag::motion (GdkEvent* event, bool first_move)
+RegionCreateDrag::motion (GdkEvent* /*event*/, bool first_move)
 {
        if (first_move) {
                // TODO: create region-create-drag region view here
@@ -1420,7 +1414,7 @@ RegionCreateDrag::finished (GdkEvent* event, bool movement_occurred)
 
 
 void
-RegionGainDrag::motion (GdkEvent* event, bool)
+RegionGainDrag::motion (GdkEvent* /*event*/, bool)
 {
        
 }
@@ -1513,12 +1507,8 @@ TrimDrag::motion (GdkEvent* event, bool first_move)
                _editor->snap_to (_current_pointer_frame);
        }
 
-       if (_current_pointer_frame == _last_pointer_frame) {
-               return;
-       }
-
        if (first_move) {
-       
+
                string trim_type;
 
                switch (_operation) {
@@ -1555,6 +1545,10 @@ TrimDrag::motion (GdkEvent* event, bool first_move)
                }
        }
 
+       if (_current_pointer_frame == _last_pointer_frame) {
+               return;
+       }
+
        if (left_direction) {
                frame_delta = (_last_pointer_frame - _current_pointer_frame);
        } else {
@@ -1694,11 +1688,7 @@ MeterMarkerDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor)
 void
 MeterMarkerDrag::motion (GdkEvent* event, bool)
 {
-       nframes64_t adjusted_frame = adjusted_current_frame ();
-       
-       if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) {
-               _editor->snap_to (adjusted_frame);
-       }
+       nframes64_t const adjusted_frame = adjusted_current_frame (event);
        
        if (adjusted_frame == _last_pointer_frame) {
                return;
@@ -1750,7 +1740,7 @@ TempoMarkerDrag::TempoMarkerDrag (Editor* e, ArdourCanvas::Item* i, bool c)
        : Drag (e, i),
          _copy (c)
 {
-       TempoMarker* _marker = reinterpret_cast<TempoMarker*> (_item->get_data ("marker"));
+       _marker = reinterpret_cast<TempoMarker*> (_item->get_data ("marker"));
        assert (_marker);
 }
 
@@ -1788,11 +1778,7 @@ TempoMarkerDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor)
 void
 TempoMarkerDrag::motion (GdkEvent* event, bool)
 {
-       nframes64_t adjusted_frame = adjusted_current_frame ();
-
-       if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) {
-               _editor->snap_to (adjusted_frame);
-       }
+       nframes64_t const adjusted_frame = adjusted_current_frame (event);
        
        if (adjusted_frame == _last_pointer_frame) {
                return;
@@ -1877,22 +1863,14 @@ CursorDrag::start_grab (GdkEvent* event, Gdk::Cursor* c)
                }
        }
 
-       _pointer_frame_offset = _grab_frame - _cursor->current_frame;   
-       
        _editor->show_verbose_time_cursor (_cursor->current_frame, 10);
 }
 
 void
 CursorDrag::motion (GdkEvent* event, bool)
 {
-       nframes64_t adjusted_frame = adjusted_current_frame ();
-       
-       if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) {
-               if (_cursor == _editor->playhead_cursor) {
-                       _editor->snap_to (adjusted_frame);
-               }
-       }
-       
+       nframes64_t const adjusted_frame = adjusted_current_frame (event);
+
        if (adjusted_frame == _last_pointer_frame) {
                return;
        }
@@ -1902,7 +1880,7 @@ CursorDrag::motion (GdkEvent* event, bool)
        _editor->show_verbose_time_cursor (_cursor->current_frame, 10);
 
 #ifdef GTKOSX
-       _editor->track_canvas->update_now ();
+       _editor->update_canvas_now ();
 #endif
        _editor->UpdateAllTransportClocks (_cursor->current_frame);
 
@@ -1950,11 +1928,7 @@ FadeInDrag::motion (GdkEvent* event, bool)
 {
        nframes64_t fade_length;
 
-       nframes64_t pos = adjusted_current_frame ();
-
-       if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) {
-               _editor->snap_to (pos);
-       }
+       nframes64_t const pos = adjusted_current_frame (event);
        
        boost::shared_ptr<Region> region = _primary->region ();
 
@@ -1989,8 +1963,8 @@ FadeInDrag::finished (GdkEvent* event, bool movement_occurred)
 
        nframes64_t fade_length;
 
-       nframes64_t const pos = adjusted_current_frame ();
-
+       nframes64_t const pos = adjusted_current_frame (event);
+       
        boost::shared_ptr<Region> region = _primary->region ();
 
        if (pos < (region->position() + 64)) {
@@ -2046,11 +2020,7 @@ FadeOutDrag::motion (GdkEvent* event, bool)
 {
        nframes64_t fade_length;
 
-       nframes64_t pos = adjusted_current_frame ();
-
-       if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) {
-               _editor->snap_to (pos);
-       }
+       nframes64_t const pos = adjusted_current_frame (event);
 
        boost::shared_ptr<Region> region = _primary->region ();
        
@@ -2087,11 +2057,7 @@ FadeOutDrag::finished (GdkEvent* event, bool movement_occurred)
 
        nframes64_t fade_length;
 
-       nframes64_t pos = adjusted_current_frame ();
-
-       if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) {
-               _editor->snap_to (pos);
-       }
+       nframes64_t const pos = adjusted_current_frame (event);
 
        boost::shared_ptr<Region> region = _primary->region ();
 
@@ -2239,13 +2205,9 @@ MarkerDrag::motion (GdkEvent* event, bool)
        Location  *real_location;
        Location *copy_location = 0;
 
-       nframes64_t newframe = adjusted_current_frame ();
+       nframes64_t const newframe = adjusted_current_frame (event);
 
        nframes64_t next = newframe;
-
-       if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) {
-               _editor->snap_to (newframe, 0, true);
-       }
        
        if (_current_pointer_frame == _last_pointer_frame) { 
                return;
@@ -2380,7 +2342,7 @@ MarkerDrag::motion (GdkEvent* event, bool)
        _editor->show_verbose_time_cursor (newframe, 10);
 
 #ifdef GTKOSX
-       _editor->track_canvas->update_now ();
+       _editor->update_canvas_now ();
 #endif
        _editor->edit_point_clock.set (copy_location->start());
 }
@@ -2463,13 +2425,13 @@ ControlPointDrag::ControlPointDrag (Editor* e, ArdourCanvas::Item* i)
          _cumulative_x_drag (0),
          _cumulative_y_drag (0)
 {
-       ControlPoint* _point = reinterpret_cast<ControlPoint*> (_item->get_data ("control_point"));
+       _point = reinterpret_cast<ControlPoint*> (_item->get_data ("control_point"));
        assert (_point);
 }
 
 
 void
-ControlPointDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor)
+ControlPointDrag::start_grab (GdkEvent* event, Gdk::Cursor* /*cursor*/)
 {
        Drag::start_grab (event, _editor->fader_cursor);
 
@@ -2567,6 +2529,18 @@ ControlPointDrag::finished (GdkEvent* event, bool movement_occurred)
        _point->line().end_drag (_point);
 }
 
+bool
+ControlPointDrag::active (Editing::MouseMode m)
+{
+       if (m == Editing::MouseGain) {
+               /* always active in mouse gain */
+               return true;
+       }
+
+       /* otherwise active if the point is on an automation line (ie not if its on a region gain line) */
+       return dynamic_cast<AutomationLine*> (&(_point->line())) != 0;
+}
+
 LineDrag::LineDrag (Editor* e, ArdourCanvas::Item* i)
        : Drag (e, i),
          _line (0),
@@ -2575,7 +2549,7 @@ LineDrag::LineDrag (Editor* e, ArdourCanvas::Item* i)
 
 }
 void
-LineDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor)
+LineDrag::start_grab (GdkEvent* event, Gdk::Cursor* /*cursor*/)
 {
        _line = reinterpret_cast<AutomationLine*> (_item->get_data ("line"));
        assert (_line);
@@ -2737,17 +2711,17 @@ RubberbandSelectDrag::finished (GdkEvent* event, bool movement_occurred)
 
 
                Selection::Operation op = Keyboard::selection_type (event->button.state);
-               bool commit;
+               bool committed;
 
                _editor->begin_reversible_command (_("rubberband selection"));
 
                if (_grab_frame < _last_pointer_frame) {
-                       commit = _editor->select_all_within (_grab_frame, _last_pointer_frame, y1, y2, _editor->track_views, op);
+                       committed = _editor->select_all_within (_grab_frame, _last_pointer_frame, y1, y2, _editor->track_views, op);
                } else {
-                       commit = _editor->select_all_within (_last_pointer_frame, _grab_frame, y1, y2, _editor->track_views, op);
+                       committed = _editor->select_all_within (_last_pointer_frame, _grab_frame, y1, y2, _editor->track_views, op);
                }               
 
-               if (commit) {
+               if (!committed) {
                        _editor->commit_reversible_command ();
                }
                
@@ -2794,7 +2768,7 @@ TimeFXDrag::motion (GdkEvent* event, bool)
 }
 
 void
-TimeFXDrag::finished (GdkEvent* event, bool movement_occurred)
+TimeFXDrag::finished (GdkEvent* /*event*/, bool movement_occurred)
 {
        _primary->get_time_axis_view().hide_timestretch ();
 
@@ -2830,6 +2804,27 @@ TimeFXDrag::finished (GdkEvent* event, bool movement_occurred)
        }
 }
 
+void
+ScrubDrag::start_grab (GdkEvent* event, Gdk::Cursor *)
+{
+       Drag::start_grab (event);
+}
+
+void
+ScrubDrag::motion (GdkEvent* /*event*/, bool)
+{
+       _editor->scrub ();
+}
+
+void
+ScrubDrag::finished (GdkEvent* /*event*/, bool movement_occurred)
+{
+       if (movement_occurred && _editor->session) {
+               /* make sure we stop */
+               _editor->session->request_transport_speed (0.0);
+       } 
+}
+
 SelectionDrag::SelectionDrag (Editor* e, ArdourCanvas::Item* i, Operation o)
        : Drag (e, i),
          _operation (o),
@@ -2902,12 +2897,8 @@ SelectionDrag::motion (GdkEvent* event, bool first_move)
        nframes64_t end = 0;
        nframes64_t length;
 
-       nframes64_t pending_position = adjusted_current_frame ();
+       nframes64_t const pending_position = adjusted_current_frame (event);
        
-       if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) {
-               _editor->snap_to (pending_position);
-       }
-
        /* only alter selection if the current frame is 
           different from the last frame position (adjusted)
         */
@@ -3002,7 +2993,7 @@ SelectionDrag::motion (GdkEvent* event, bool first_move)
                break;
        }
        
-       if (event->button.x >= _editor->horizontal_adjustment.get_value() + _editor->canvas_width) {
+       if (event->button.x >= _editor->horizontal_adjustment.get_value() + _editor->_canvas_width) {
                _editor->start_canvas_autoscroll (1, 0);
        }
 
@@ -3157,7 +3148,7 @@ RangeMarkerBarDrag::motion (GdkEvent* event, bool first_move)
                break;          
        }
        
-       if (event->button.x >= _editor->horizontal_adjustment.get_value() + _editor->canvas_width) {
+       if (event->button.x >= _editor->horizontal_adjustment.get_value() + _editor->_canvas_width) {
                _editor->start_canvas_autoscroll (1, 0);
        }
        
@@ -3187,6 +3178,7 @@ RangeMarkerBarDrag::finished (GdkEvent* event, bool movement_occurred)
        
        if (movement_occurred) {
                motion (event, false);
+               _drag_rect->hide();
 
                switch (_operation) {
                case CreateRangeMarker:
@@ -3208,15 +3200,12 @@ RangeMarkerBarDrag::finished (GdkEvent* event, bool movement_occurred)
                        XMLNode &after = _editor->session->locations()->get_state();
                        _editor->session->add_command(new MementoCommand<Locations>(*(_editor->session->locations()), &before, &after));
                        _editor->commit_reversible_command ();
-                       
-                       _drag_rect->hide();
                        break;
                    }
 
                case CreateTransportMarker:
                        // popup menu to pick loop or punch
                        _editor->new_transport_marker_context_menu (&event->button, _item);
-                       
                        break;
                }
        } else {