make step edit cursor follow zoom (and change its color a bit)
[ardour.git] / gtk2_ardour / editor_drag.cc
index 30211049c6c65255e3bc2d22405c510f68d0aa3a..98ceca5b8ae0330201bc8ba703e2a7690dda3001 100644 (file)
@@ -215,8 +215,8 @@ Drag::start_grab (GdkEvent* event, Gdk::Cursor *cursor)
        _last_pointer_y = _grab_y;
 
        _item->grab (Gdk::POINTER_MOTION_MASK|Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK,
-                             *cursor,
-                             event->button.time);
+                     *cursor,
+                     event->button.time);
 
        if (_editor->session() && _editor->session()->transport_rolling()) {
                _was_rolling = true;
@@ -303,7 +303,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, allow_vertical_autoscroll ());
+                               _editor->maybe_autoscroll (true, allow_vertical_autoscroll ());
                        }
 
                        motion (event, _move_threshold_passed != old_move_threshold_passed);
@@ -1590,9 +1590,9 @@ NoteResizeDrag::NoteResizeDrag (Editor* e, ArdourCanvas::Item* i)
 }
 
 void
-NoteResizeDrag::start_grab (GdkEvent* event, Gdk::Cursor *)
+NoteResizeDrag::start_grab (GdkEvent* event, Gdk::Cursor* /*ignored*/)
 {
-       Gdk::Cursor cursor;
+       Gdk::Cursor* cursor;
        ArdourCanvas::CanvasNote* cnote = dynamic_cast<ArdourCanvas::CanvasNote*>(_item);
 
        Drag::start_grab (event);
@@ -1603,14 +1603,14 @@ NoteResizeDrag::start_grab (GdkEvent* event, Gdk::Cursor *)
        double const middle_point = region_start + cnote->x1() + (cnote->x2() - cnote->x1()) / 2.0L;
 
        if (grab_x() <= middle_point) {
-               cursor = Gdk::Cursor(Gdk::LEFT_SIDE);
+               cursor = _editor->left_side_trim_cursor;
                at_front = true;
        } else {
-               cursor = Gdk::Cursor(Gdk::RIGHT_SIDE);
+               cursor = _editor->right_side_trim_cursor;
                at_front = false;
        }
 
-       _item->grab(GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK, cursor, event->motion.time);
+       _item->grab(GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK, *cursor, event->motion.time);
 
        if (event->motion.state & Keyboard::PrimaryModifier) {
                relative = false;
@@ -1699,25 +1699,26 @@ TrimDrag::start_grab (GdkEvent* event, Gdk::Cursor *)
                speed = tv->track()->speed();
        }
 
-       nframes64_t region_start = (nframes64_t) (_primary->region()->position() / speed);
-       nframes64_t region_end = (nframes64_t) (_primary->region()->last_frame() / speed);
-       nframes64_t region_length = (nframes64_t) (_primary->region()->length() / speed);
-
-       Drag::start_grab (event, _editor->trimmer_cursor);
+       nframes64_t const region_start = (nframes64_t) (_primary->region()->position() / speed);
+       nframes64_t const region_end = (nframes64_t) (_primary->region()->last_frame() / speed);
+       nframes64_t const region_length = (nframes64_t) (_primary->region()->length() / speed);
 
        nframes64_t const pf = adjusted_current_frame (event);
 
        if (Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) {
                _operation = ContentsTrim;
+                Drag::start_grab (event, _editor->trimmer_cursor);
        } else {
                /* These will get overridden for a point trim.*/
                if (pf < (region_start + region_length/2)) {
                        /* closer to start */
                        _operation = StartTrim;
-               } else if (pf > (region_end - region_length/2)) {
+                        Drag::start_grab (event, _editor->left_side_trim_cursor);
+               } else {
                        /* closer to end */
                        _operation = EndTrim;
-               }
+                        Drag::start_grab (event, _editor->right_side_trim_cursor);
+                }
        }
 
        switch (_operation) {
@@ -1776,6 +1777,7 @@ TrimDrag::motion (GdkEvent* event, bool first_move)
                for (list<DraggingView>::const_iterator i = _views.begin(); i != _views.end(); ++i) {
                        RegionView* rv = i->view;
                        rv->fake_set_opaque(false);
+                       rv->enable_display (false);
                         rv->region()->clear_history ();
                        rv->region()->suspend_property_changes ();
 
@@ -1867,6 +1869,7 @@ TrimDrag::finished (GdkEvent* event, bool movement_occurred)
 
                        for (list<DraggingView>::const_iterator i = _views.begin(); i != _views.end(); ++i) {
                                _editor->thaw_region_after_trim (*i->view);
+                               i->view->enable_display (true);
                                i->view->fake_set_opaque (true);
                                 if (_have_transaction) {
                                         _editor->session()->add_command (new StatefulDiffCommand (i->view->region()));
@@ -2107,12 +2110,24 @@ CursorDrag::start_grab (GdkEvent* event, Gdk::Cursor* c)
        if (_cursor == _editor->playhead_cursor) {
                _editor->_dragging_playhead = true;
 
-               if (_editor->session() && _was_rolling && _stop) {
-                       _editor->session()->request_stop ();
-               }
+               Session* s = _editor->session ();
+
+               if (s) {
+                       if (_was_rolling && _stop) {
+                               s->request_stop ();
+                       }
+
+                       if (s->is_auditioning()) {
+                               s->cancel_audition ();
+                       }
+
+                       s->request_suspend_timecode_transmission ();
 
-               if (_editor->session() && _editor->session()->is_auditioning()) {
-                       _editor->session()->cancel_audition ();
+                       if (s->timecode_transmission_suspended ()) {
+                               nframes64_t const f = _editor->playhead_cursor->current_frame;
+                               s->send_mmc_locate (f);
+                               s->send_full_time_code (f);
+                       }
                }
        }
 
@@ -2134,6 +2149,14 @@ CursorDrag::motion (GdkEvent* event, bool)
 
        _editor->show_verbose_time_cursor (_cursor->current_frame, 10);
 
+       Session* s = _editor->session ();
+       if (s && _item == &_editor->playhead_cursor->canvas_item && s->timecode_transmission_suspended ()) {
+               nframes64_t const f = _editor->playhead_cursor->current_frame;
+               s->send_mmc_locate (f);
+               s->send_full_time_code (f);
+       }
+       
+
 #ifdef GTKOSX
        _editor->update_canvas_now ();
 #endif
@@ -2152,9 +2175,11 @@ CursorDrag::finished (GdkEvent* event, bool movement_occurred)
        motion (event, false);
 
        if (_item == &_editor->playhead_cursor->canvas_item) {
-               if (_editor->session()) {
-                       _editor->session()->request_locate (_editor->playhead_cursor->current_frame, _was_rolling);
+               Session* s = _editor->session ();
+               if (s) {
+                       s->request_locate (_editor->playhead_cursor->current_frame, _was_rolling);
                        _editor->_pending_locate_request = true;
+                       s->request_resume_timecode_transmission ();
                }
        }
 }
@@ -2162,7 +2187,11 @@ CursorDrag::finished (GdkEvent* event, bool movement_occurred)
 void
 CursorDrag::aborted ()
 {
-       _editor->_dragging_playhead = false;
+       if (_editor->_dragging_playhead) {
+               _editor->session()->request_resume_timecode_transmission ();
+               _editor->_dragging_playhead = false;
+       }
+       
        _cursor->set_position (adjusted_frame (grab_frame (), 0, false));
 }
 
@@ -2182,6 +2211,7 @@ FadeInDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor)
 
        _pointer_frame_offset = grab_frame() - ((nframes64_t) r->fade_in()->back()->when + r->position());
        _editor->show_verbose_duration_cursor (r->position(), r->position() + r->fade_in()->back()->when, 10);
+       
 }
 
 void
@@ -2802,7 +2832,7 @@ ControlPointDrag::finished (GdkEvent* event, bool movement_occurred)
 
                /* just a click */
 
-               if ((event->type == GDK_BUTTON_RELEASE) && (event->button.button == 1) && Keyboard::modifier_state_equals (event->button.state, Keyboard::TertiaryModifier)) {
+               if (Keyboard::modifier_state_equals (event->button.state, Keyboard::TertiaryModifier)) {
                        _editor->reset_point_selection ();
                }
 
@@ -2926,6 +2956,76 @@ LineDrag::aborted ()
        _line->reset ();
 }
 
+FeatureLineDrag::FeatureLineDrag (Editor* e, ArdourCanvas::Item* i)
+       : Drag (e, i),
+         _line (0),
+         _cumulative_x_drag (0)
+{
+
+}
+void
+FeatureLineDrag::start_grab (GdkEvent* event, Gdk::Cursor* /*cursor*/)
+{
+  
+       Drag::start_grab (event);
+       
+       _line = reinterpret_cast<SimpleLine*> (_item);
+       assert (_line);
+
+       /* need to get x coordinate in terms of parent (AudioRegionView) origin. */
+
+       double cx = event->button.x;
+       double cy = event->button.y;
+
+       _item->property_parent().get_value()->w2i(cx, cy);
+
+       /* store grab start in parent frame */
+       _region_view_grab_x = cx;
+       
+       _before = _line->property_x1();
+       
+       _arv = reinterpret_cast<AudioRegionView*> (_item->get_data ("regionview"));
+               
+       _max_x = _editor->frame_to_pixel(_arv->get_duration());
+}
+
+void
+FeatureLineDrag::motion (GdkEvent* event, bool)
+{
+       double dx = _drags->current_pointer_x() - last_pointer_x();
+       
+       double cx = _region_view_grab_x + _cumulative_x_drag + dx;
+       
+       _cumulative_x_drag += dx;
+               
+       /* Clamp the min and max extent of the drag to keep it within the region view bounds */
+       
+       if (cx > _max_x){
+               cx = _max_x;
+       }
+       else if(cx < 0){
+               cx = 0;
+       }
+       
+       _line->property_x1() = cx; 
+       _line->property_x2() = cx;
+
+       _before = _line->property_x1();
+}
+
+void
+FeatureLineDrag::finished (GdkEvent* event, bool)
+{
+       _arv = reinterpret_cast<AudioRegionView*> (_item->get_data ("regionview"));
+       _arv->update_transient(_before, _line->property_x1());
+}
+
+void
+FeatureLineDrag::aborted ()
+{
+       //_line->reset ();
+}
+
 void
 RubberbandSelectDrag::start_grab (GdkEvent* event, Gdk::Cursor *)
 {
@@ -3007,9 +3107,9 @@ RubberbandSelectDrag::finished (GdkEvent* event, bool movement_occurred)
                _editor->begin_reversible_command (_("rubberband selection"));
 
                if (grab_frame() < last_pointer_frame()) {
-                       committed = _editor->select_all_within (grab_frame(), last_pointer_frame() - 1, y1, y2, _editor->track_views, op);
+                       committed = _editor->select_all_within (grab_frame(), last_pointer_frame() - 1, y1, y2, _editor->track_views, op, false);
                } else {
-                       committed = _editor->select_all_within (last_pointer_frame(), grab_frame() - 1, y1, y2, _editor->track_views, op);
+                       committed = _editor->select_all_within (last_pointer_frame(), grab_frame() - 1, y1, y2, _editor->track_views, op, false);
                }
 
                if (!committed) {
@@ -3164,7 +3264,7 @@ SelectionDrag::start_grab (GdkEvent* event, Gdk::Cursor*)
                if (_editor->clicked_axisview) {
                        _editor->clicked_axisview->order_selection_trims (_item, true);
                }
-               Drag::start_grab (event, _editor->trimmer_cursor);
+               Drag::start_grab (event, _editor->left_side_trim_cursor);
                start = _editor->selection->time[_editor->clicked_selection].start;
                _pointer_frame_offset = grab_frame() - start;
                break;
@@ -3173,7 +3273,7 @@ SelectionDrag::start_grab (GdkEvent* event, Gdk::Cursor*)
                if (_editor->clicked_axisview) {
                        _editor->clicked_axisview->order_selection_trims (_item, false);
                }
-               Drag::start_grab (event, _editor->trimmer_cursor);
+               Drag::start_grab (event, _editor->right_side_trim_cursor);
                end = _editor->selection->time[_editor->clicked_selection].end;
                _pointer_frame_offset = grab_frame() - end;
                break;
@@ -3404,7 +3504,7 @@ RangeMarkerBarDrag::start_grab (GdkEvent* event, Gdk::Cursor *)
        Gdk::Cursor* cursor = 0;
 
        if (!_editor->temp_location) {
-               _editor->temp_location = new Location;
+               _editor->temp_location = new Location (*_editor->session());
        }
 
        switch (_operation) {
@@ -3525,7 +3625,10 @@ RangeMarkerBarDrag::finished (GdkEvent* event, bool movement_occurred)
                                flags = Location::IsRangeMarker;
                                _editor->range_bar_drag_rect->hide();
                        }
-                       newloc = new Location(_editor->temp_location->start(), _editor->temp_location->end(), rangename, (Location::Flags) flags);
+                       newloc = new Location (
+                               *_editor->session(), _editor->temp_location->start(), _editor->temp_location->end(), rangename, (Location::Flags) flags
+                               );
+                       
                        _editor->session()->locations()->add (newloc, true);
                        XMLNode &after = _editor->session()->locations()->get_state();
                        _editor->session()->add_command(new MementoCommand<Locations>(*(_editor->session()->locations()), &before, &after));
@@ -3559,7 +3662,7 @@ RangeMarkerBarDrag::finished (GdkEvent* event, bool movement_occurred)
                        switch (_editor->mouse_mode) {
                        case MouseObject:
                                /* find the two markers on either side and then make the selection from it */
-                               _editor->select_all_within (start, end, 0.0f, FLT_MAX, _editor->track_views, Selection::Set);
+                               _editor->select_all_within (start, end, 0.0f, FLT_MAX, _editor->track_views, Selection::Set, false);
                                break;
 
                        case MouseRange:
@@ -3772,7 +3875,7 @@ NoteDrag::motion (GdkEvent*, bool)
                region->move_selection (dx, dy);
 
                 char buf[12];
-                snprintf (buf, sizeof (buf), "%s (%d)", Evoral::midi_note_name (cnote->note()->note()).c_str(),
+                snprintf (buf, sizeof (buf), "%s (%d)", Evoral::midi_note_name (cnote->note()->note() + drag_delta_note).c_str(),
                           (int) floor ((cnote->note()->note() + drag_delta_note)));
                _editor->show_verbose_canvas_cursor_with (buf);
         }