make mouse range mode do something interesting when in internal/note edit mode. not...
[ardour.git] / gtk2_ardour / editor_drag.cc
index e07844f7a9091f15f867d25fdaa3943fad7624fa..5201d3346df98d3bae2661067ea0a1b6b9f79439 100644 (file)
@@ -205,19 +205,15 @@ Drag::swap_grab (ArdourCanvas::Item* new_item, Gdk::Cursor* cursor, uint32_t tim
        _item = new_item;
 
        if (cursor == 0) {
-               cursor = _editor->which_grabber_cursor ();
+               _item->grab (Gdk::POINTER_MOTION_MASK | Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK, time);
+       } else {
+               _item->grab (Gdk::POINTER_MOTION_MASK | Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK, *cursor, time);
        }
-
-       _item->grab (Gdk::POINTER_MOTION_MASK | Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK, *cursor, time);
 }
 
 void
 Drag::start_grab (GdkEvent* event, Gdk::Cursor *cursor)
 {
-       if (cursor == 0) {
-               cursor = _editor->which_grabber_cursor ();
-       }
-
        // if dragging with button2, the motion is x constrained, with Alt-button2 it is y constrained
 
        if (Keyboard::is_button2_event (&event->button)) {
@@ -240,9 +236,14 @@ Drag::start_grab (GdkEvent* event, Gdk::Cursor *cursor)
        _last_pointer_x = _grab_x;
        _last_pointer_y = _grab_y;
 
-       _item->grab (Gdk::POINTER_MOTION_MASK|Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK,
-                    *cursor,
-                    event->button.time);
+       if (cursor == 0) {
+               _item->grab (Gdk::POINTER_MOTION_MASK|Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK,
+                            event->button.time);
+       } else {
+               _item->grab (Gdk::POINTER_MOTION_MASK|Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK,
+                            *cursor,
+                            event->button.time);
+       }
 
        if (_editor->session() && _editor->session()->transport_rolling()) {
                _was_rolling = true;
@@ -1932,7 +1933,7 @@ MeterMarkerDrag::motion (GdkEvent* event, bool first_move)
                // not, because we'll remove it from the map).
                
                MeterSection section (_marker->meter());
-               
+
                if (!section.movable()) {
                        return;
                }
@@ -1953,6 +1954,8 @@ MeterMarkerDrag::motion (GdkEvent* event, bool first_move)
 
                if (!_copy) {
                        TempoMap& map (_editor->session()->tempo_map());
+                       /* get current state */
+                       before_state = &map.get_state();
                        /* remove the section while we drag it */
                        map.remove_meter (section, true);
                }
@@ -1987,13 +1990,12 @@ MeterMarkerDrag::finished (GdkEvent* event, bool movement_occurred)
 
        } else {
                _editor->begin_reversible_command (_("move meter mark"));
-               XMLNode &before = map.get_state();
 
                /* we removed it before, so add it back now */
                
                map.add_meter (_marker->meter(), when);
                XMLNode &after = map.get_state();
-               _editor->session()->add_command(new MementoCommand<TempoMap>(map, &before, &after));
+               _editor->session()->add_command(new MementoCommand<TempoMap>(map, before_state, &after));
                _editor->commit_reversible_command ();
        }
 
@@ -2071,6 +2073,8 @@ TempoMarkerDrag::motion (GdkEvent* event, bool first_move)
 
                if (!_copy) {
                        TempoMap& map (_editor->session()->tempo_map());
+                       /* get current state */
+                       before_state = &map.get_state();
                        /* remove the section while we drag it */
                        map.remove_tempo (section, true);
                }
@@ -2090,10 +2094,11 @@ TempoMarkerDrag::finished (GdkEvent* event, bool movement_occurred)
 
        motion (event, false);
 
+       TempoMap& map (_editor->session()->tempo_map());
+       framepos_t beat_time = map.round_to_beat (last_pointer_frame(), 0);
        Timecode::BBT_Time when;
 
-       TempoMap& map (_editor->session()->tempo_map());
-       map.bbt_time (last_pointer_frame(), when);
+       map.bbt_time (beat_time, when);
 
        if (_copy == true) {
                _editor->begin_reversible_command (_("copy tempo mark"));
@@ -2105,11 +2110,10 @@ TempoMarkerDrag::finished (GdkEvent* event, bool movement_occurred)
 
        } else {
                _editor->begin_reversible_command (_("move tempo mark"));
-               XMLNode &before = map.get_state();
                /* we removed it before, so add it back now */
                map.add_tempo (_marker->tempo(), when);
                XMLNode &after = map.get_state();
-               _editor->session()->add_command (new MementoCommand<TempoMap>(map, &before, &after));
+               _editor->session()->add_command (new MementoCommand<TempoMap>(map, before_state, &after));
                _editor->commit_reversible_command ();
        }
 
@@ -3108,6 +3112,7 @@ FeatureLineDrag::aborted (bool)
 
 RubberbandSelectDrag::RubberbandSelectDrag (Editor* e, ArdourCanvas::Item* i)
        : Drag (e, i)
+       , _vertical_only (false)
 {
        DEBUG_TRACE (DEBUG::Drags, "New RubberbandSelectDrag\n");
 }
@@ -3159,8 +3164,14 @@ RubberbandSelectDrag::motion (GdkEvent* event, bool)
                double x2 = _editor->frame_to_pixel (end);
 
                _editor->rubberband_rect->property_x1() = x1;
+               if (_vertical_only) {
+                       /* fixed 10 pixel width */
+                       _editor->rubberband_rect->property_x2() = x1 + 10;
+               } else {
+                       _editor->rubberband_rect->property_x2() = x2;
+               } 
+
                _editor->rubberband_rect->property_y1() = y1;
-               _editor->rubberband_rect->property_x2() = x2;
                _editor->rubberband_rect->property_y2() = y2;
 
                _editor->rubberband_rect->show();
@@ -4333,6 +4344,34 @@ MidiRubberbandSelectDrag::deselect_things ()
        /* XXX */
 }
 
+MidiVerticalSelectDrag::MidiVerticalSelectDrag (Editor* e, MidiRegionView* rv)
+       : RubberbandSelectDrag (e, rv->get_canvas_frame ())
+       , _region_view (rv)
+{
+       _vertical_only = true;
+}
+
+void
+MidiVerticalSelectDrag::select_things (int button_state, framepos_t x1, framepos_t x2, double y1, double y2, bool drag_in_progress)
+{
+       double const y = _region_view->midi_view()->y_position ();
+
+       y1 = max (0.0, y1 - y);
+       y2 = max (0.0, y2 - y);
+       
+       _region_view->update_vertical_drag_selection (
+               y1,
+               y2,
+               Keyboard::modifier_state_contains (button_state, Keyboard::TertiaryModifier)
+               );
+}
+
+void
+MidiVerticalSelectDrag::deselect_things ()
+{
+       /* XXX */
+}
+
 EditorRubberbandSelectDrag::EditorRubberbandSelectDrag (Editor* e, ArdourCanvas::Item* i)
        : RubberbandSelectDrag (e, i)
 {
@@ -4446,7 +4485,7 @@ NoteCreateDrag::finished (GdkEvent* event, bool had_movement)
        framecnt_t length = abs (_note[0] - _note[1]);
 
        framecnt_t const g = grid_frames (start);
-       double const one_tick = 1 / Timecode::BBT_Time::ticks_per_bar_division;
+       double const one_tick = 1 / Timecode::BBT_Time::ticks_per_beat;
        
        if (_editor->snap_mode() == SnapNormal && length < g) {
                length = g - one_tick;