refactor MidiRegionView event handling to avoid too much spaghetti as we move along
authorPaul Davis <paul@linuxaudiosystems.com>
Thu, 27 May 2010 15:07:15 +0000 (15:07 +0000)
committerPaul Davis <paul@linuxaudiosystems.com>
Thu, 27 May 2010 15:07:15 +0000 (15:07 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@7182 d708f5d6-7413-0410-9779-e7cbd77b26cf

gtk2_ardour/midi_region_view.cc
gtk2_ardour/midi_region_view.h

index 3193da4c8a2429f35d81c24582768c7504829fd9..368bf3840b2d0f81b0fc09acd21f07bba512a314 100644 (file)
@@ -86,6 +86,7 @@ MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &
        , _delta_command(0)
        , _diff_command(0)
        , _ghost_note(0)
+        , _drag_rect (0)
        , _mouse_state(None)
        , _pressed_button(0)
        , _sort_needed (true)
@@ -109,13 +110,13 @@ MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &
        , _delta_command(0)
        , _diff_command(0)
        , _ghost_note(0)
+        , _drag_rect (0)
        , _mouse_state(None)
        , _pressed_button(0)
        , _sort_needed (true)
        , _optimization_iterator (_events.end())
        , _list_editor (0)
        , no_sound_notes (false)
-
 {
        _note_group->raise_to_top();
 }
@@ -133,6 +134,7 @@ MidiRegionView::MidiRegionView (const MidiRegionView& other)
        , _delta_command(0)
        , _diff_command(0)
        , _ghost_note(0)
+        , _drag_rect (0)
        , _mouse_state(None)
        , _pressed_button(0)
        , _sort_needed (true)
@@ -160,6 +162,7 @@ MidiRegionView::MidiRegionView (const MidiRegionView& other, boost::shared_ptr<M
        , _delta_command(0)
        , _diff_command(0)
        , _ghost_note(0)
+        , _drag_rect (0)
        , _mouse_state(None)
        , _pressed_button(0)
        , _sort_needed (true)
@@ -227,349 +230,394 @@ MidiRegionView::init (Gdk::Color const & basic_color, bool wfd)
 bool
 MidiRegionView::canvas_event(GdkEvent* ev)
 {
-       PublicEditor& editor (trackview.editor());
-
-       if (!editor.internal_editing()) {
+       if (!trackview.editor().internal_editing()) {
                return false;
        }
 
-       static double drag_start_x, drag_start_y;
-       static double last_x, last_y;
-       double event_x, event_y;
-       nframes64_t event_frame = 0;
-       bool fine;
-
-       static ArdourCanvas::SimpleRect* drag_rect = 0;
-
-       /* XXX: note that as of August 2009, the GnomeCanvas does not propagate scroll events
+       /* XXX: note that until version 2.30, the GnomeCanvas did not propagate scroll events
           to its items, which means that ev->type == GDK_SCROLL will never be seen
        */
 
        switch (ev->type) {
        case GDK_SCROLL:
-               fine = Keyboard::modifier_state_equals (ev->scroll.state, Keyboard::Level4Modifier);
-
-               if (ev->scroll.direction == GDK_SCROLL_UP) {
-                       change_velocities (true, fine, false);
-                       return true;
-               } else if (ev->scroll.direction == GDK_SCROLL_DOWN) {
-                       change_velocities (false, fine, false);
-                       return true;
-               } else {
-                       return false;
-               }
-               break;
+                return scroll (&ev->scroll);
 
        case GDK_KEY_PRESS:
+                return key_press (&ev->key);
 
-               /* since GTK bindings are generally activated on press, and since
-                  detectable auto-repeat is the name of the game and only sends
-                  repeated presses, carry out key actions at key press, not release.
-               */
-
-               if (ev->key.keyval == GDK_Alt_L || ev->key.keyval == GDK_Alt_R){
-                       _mouse_state = SelectTouchDragging;
-                       return true;
-
-               } else if (ev->key.keyval == GDK_Escape) {
-                       clear_selection();
-                       _mouse_state = None;
-
-               } else if (ev->key.keyval == GDK_comma || ev->key.keyval == GDK_period) {
-
-                       bool start = (ev->key.keyval == GDK_comma);
-                       bool end = (ev->key.keyval == GDK_period);
-                       bool shorter = Keyboard::modifier_state_contains (ev->key.state, Keyboard::PrimaryModifier);
-                       fine = Keyboard::modifier_state_contains (ev->key.state, Keyboard::SecondaryModifier);
-
-                       change_note_lengths (fine, shorter, start, end);
+       case GDK_KEY_RELEASE:
+                return key_release (&ev->key);
 
-                       return true;
+       case GDK_BUTTON_PRESS:
+                return button_press (&ev->button);
 
-               } else if (ev->key.keyval == GDK_Delete) {
+       case GDK_2BUTTON_PRESS:
+               return true;
 
-                       delete_selection();
-                       return true;
+       case GDK_BUTTON_RELEASE:
+                return button_release (&ev->button);
+               
+       case GDK_ENTER_NOTIFY:
+                return enter_notify (&ev->crossing);
 
-               } else if (ev->key.keyval == GDK_Tab) {
+       case GDK_LEAVE_NOTIFY:
+                return leave_notify (&ev->crossing);
 
-                       if (Keyboard::modifier_state_equals (ev->key.state, Keyboard::PrimaryModifier)) {
-                               goto_previous_note ();
-                       } else {
-                               goto_next_note ();
-                       }
-                       return true;
+       case GDK_MOTION_NOTIFY:
+                return motion (&ev->motion);
 
-               } else if (ev->key.keyval == GDK_Up) {
+       default: 
+                break;
+       }
 
-                       bool allow_smush = Keyboard::modifier_state_contains (ev->key.state, Keyboard::SecondaryModifier);
-                       bool fine = Keyboard::modifier_state_contains (ev->key.state, Keyboard::TertiaryModifier);
+       return false;
+}
 
-                       if (Keyboard::modifier_state_contains (ev->key.state, Keyboard::PrimaryModifier)) {
-                               change_velocities (true, fine, allow_smush);
-                       } else {
-                               transpose (true, fine, allow_smush);
-                       }
-                       return true;
+bool
+MidiRegionView::enter_notify (GdkEventCrossing* ev)
+{
+        /* FIXME: do this on switch to note tool, too, if the pointer is already in */
+        Keyboard::magic_widget_grab_focus();
+        group->grab_focus();
+        
+        if (trackview.editor().current_mouse_mode() == MouseRange) {
+                create_ghost_note (ev->x, ev->y);
+        }
 
-               } else if (ev->key.keyval == GDK_Down) {
+        return false;
+}
 
-                       bool allow_smush = Keyboard::modifier_state_contains (ev->key.state, Keyboard::SecondaryModifier);
-                       fine = Keyboard::modifier_state_contains (ev->key.state, Keyboard::TertiaryModifier);
+bool
+MidiRegionView::leave_notify (GdkEventCrossing* ev)
+{
+        trackview.editor().hide_verbose_canvas_cursor ();
+        delete _ghost_note;
+        _ghost_note = 0;
+        return false;
+}
 
-                       if (Keyboard::modifier_state_contains (ev->key.state, Keyboard::PrimaryModifier)) {
-                               change_velocities (false, fine, allow_smush);
-                       } else {
-                               transpose (false, fine, allow_smush);
-                       }
-                       return true;
+bool
+MidiRegionView::button_press (GdkEventButton* ev)
+{
+        _last_x = ev->x;
+        _last_y = ev->y;
+        group->w2i (_last_x, _last_y);
+        
+        if (_mouse_state != SelectTouchDragging && ev->button == 1) {
+                _pressed_button = ev->button;
+                _mouse_state = Pressed;
+                return true;
+        }
+        _pressed_button = ev->button;
 
-               } else if (ev->key.keyval == GDK_Left) {
+        return true;
+}
 
-                       nudge_notes (false);
-                       return true;
+bool
+MidiRegionView::button_release (GdkEventButton* ev)
+{
+       double event_x, event_y;
+       nframes64_t event_frame = 0;
 
-               } else if (ev->key.keyval == GDK_Right) {
+        event_x = ev->x;
+        event_y = ev->y;
+        group->w2i(event_x, event_y);
+        group->ungrab(ev->time);
+        event_frame = trackview.editor().pixel_to_frame(event_x);
 
-                       nudge_notes (true);
-                       return true;
+        if (ev->button == 3) {
+                return false;
+        } else if (_pressed_button != 1) {
+                return false;
+        }
 
-               } else if (ev->key.keyval == GDK_Control_L) {
-                       return true;
+        switch (_mouse_state) {
+        case Pressed: // Clicked
+                switch (trackview.editor().current_mouse_mode()) {
+                case MouseObject:
+                case MouseTimeFX:
+                        clear_selection();
+                        break;
+                case MouseRange:
+                {
+                        bool success;
+                        Evoral::MusicalTime beats = trackview.editor().get_grid_type_as_beats (success, trackview.editor().pixel_to_frame (event_x));
+                        if (!success) {
+                                beats = 1;
+                        }
 
-               } else if (ev->key.keyval == GDK_r) {
-                       /* if we're not step editing, this really doesn't matter */
-                       midi_view()->step_edit_rest ();
-                       return true;
-               }
+                        create_note_at (event_x, event_y, beats);
+                        break;
+                }
+                default:
+                        break;
+                }
+                _mouse_state = None;
+                break;
+        case SelectRectDragging: // Select drag done
+                _mouse_state = None;
+                delete _drag_rect;
+                _drag_rect = 0;
+                break;
+
+        case AddDragging: // Add drag done
+                _mouse_state = None;
+                if (_drag_rect->property_x2() > _drag_rect->property_x1() + 2) {
+                        const double x      = _drag_rect->property_x1();
+                        const double length = trackview.editor().pixel_to_frame 
+                                (_drag_rect->property_x2() - _drag_rect->property_x1());
+
+                        create_note_at (x, _drag_rect->property_y1(), frames_to_beats(length));
+                }
 
-               return false;
+                delete _drag_rect;
+                _drag_rect = 0;
 
-       case GDK_KEY_RELEASE:
-               if (ev->key.keyval == GDK_Alt_L || ev->key.keyval == GDK_Alt_R) {
-                       _mouse_state = None;
-                       return true;
-               }
-               return false;
+                create_ghost_note (ev->x, ev->y);
 
-       case GDK_BUTTON_PRESS:
-               last_x = ev->button.x;
-               last_y = ev->button.y;
-               group->w2i (last_x, last_y);
-
-               if (_mouse_state != SelectTouchDragging && ev->button.button == 1) {
-                       _pressed_button = ev->button.button;
-                       _mouse_state = Pressed;
-                       return true;
-               }
-               _pressed_button = ev->button.button;
-               return true;
+        default:
+                break;
+        }
 
-       case GDK_2BUTTON_PRESS:
-               return true;
+        return false;
+}
 
-       case GDK_ENTER_NOTIFY:
-       {
-               /* FIXME: do this on switch to note tool, too, if the pointer is already in */
-               Keyboard::magic_widget_grab_focus();
-               group->grab_focus();
+bool
+MidiRegionView::motion (GdkEventMotion* ev)
+{
+       double event_x, event_y;
+       nframes64_t event_frame = 0;
 
-               if (editor.current_mouse_mode() == MouseRange) {
-                       create_ghost_note (ev->crossing.x, ev->crossing.y);
-               }
-               break;
-       }
+        event_x = ev->x;
+        event_y = ev->y;
+        group->w2i(event_x, event_y);
 
-       case GDK_LEAVE_NOTIFY:
-       {
-               trackview.editor().hide_verbose_canvas_cursor ();
-               delete _ghost_note;
-               _ghost_note = 0;
-               break;
-       }
+        // convert event_x to global frame
+        event_frame = trackview.editor().pixel_to_frame(event_x) + _region->position();
+        trackview.editor().snap_to(event_frame);
+        // convert event_frame back to local coordinates relative to position
+        event_frame -= _region->position();
 
-       case GDK_MOTION_NOTIFY:
-       {
-               event_x = ev->motion.x;
-               event_y = ev->motion.y;
-               group->w2i(event_x, event_y);
-
-               // convert event_x to global frame
-               event_frame = trackview.editor().pixel_to_frame(event_x) + _region->position();
-               trackview.editor().snap_to(event_frame);
-               // convert event_frame back to local coordinates relative to position
-               event_frame -= _region->position();
-
-               if (_ghost_note) {
-                       update_ghost_note (ev->motion.x, ev->motion.y);
-               }
+        if (_ghost_note) {
+                update_ghost_note (ev->x, ev->y);
+        }
                
-               switch (_mouse_state) {
-               case Pressed: // Maybe start a drag, if we've moved a bit
+        switch (_mouse_state) {
+        case Pressed: // Maybe start a drag, if we've moved a bit
 
-                       if (fabs (event_x - last_x) < 1 && fabs (event_y - last_y) < 1) {
-                               /* no appreciable movement since the button was pressed */
-                               return false;
-                       }
+                if (fabs (event_x - _last_x) < 1 && fabs (event_y - _last_y) < 1) {
+                        /* no appreciable movement since the button was pressed */
+                        return false;
+                }
 
-                       // Select drag start
-                       if (_pressed_button == 1 && editor.current_mouse_mode() == MouseObject) {
-                               group->grab(GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
-                                               Gdk::Cursor(Gdk::FLEUR), ev->motion.time);
-                               last_x = event_x;
-                               last_y = event_y;
-                               drag_start_x = event_x;
-                               drag_start_y = event_y;
-
-                               drag_rect = new ArdourCanvas::SimpleRect(*group);
-                               drag_rect->property_x1() = event_x;
-                               drag_rect->property_y1() = event_y;
-                               drag_rect->property_x2() = event_x;
-                               drag_rect->property_y2() = event_y;
-                               drag_rect->property_outline_what() = 0xFF;
-                               drag_rect->property_outline_color_rgba()
-                                       = ARDOUR_UI::config()->canvasvar_MidiSelectRectOutline.get();
-                               drag_rect->property_fill_color_rgba()
-                                       = ARDOUR_UI::config()->canvasvar_MidiSelectRectFill.get();
-
-                               _mouse_state = SelectRectDragging;
-                               return true;
+                // Select drag start
+                if (_pressed_button == 1 && trackview.editor().current_mouse_mode() == MouseObject) {
+                        group->grab(GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
+                                    Gdk::Cursor(Gdk::FLEUR), ev->time);
+                        _last_x = event_x;
+                        _last_y = event_y;
+                        _drag_start_x = event_x;
+                        _drag_start_y = event_y;
+
+                        _drag_rect = new ArdourCanvas::SimpleRect(*group);
+                        _drag_rect->property_x1() = event_x;
+                        _drag_rect->property_y1() = event_y;
+                        _drag_rect->property_x2() = event_x;
+                        _drag_rect->property_y2() = event_y;
+                        _drag_rect->property_outline_what() = 0xFF;
+                        _drag_rect->property_outline_color_rgba()
+                                = ARDOUR_UI::config()->canvasvar_MidiSelectRectOutline.get();
+                        _drag_rect->property_fill_color_rgba()
+                                = ARDOUR_UI::config()->canvasvar_MidiSelectRectFill.get();
+
+                        _mouse_state = SelectRectDragging;
+                        return true;
 
                        // Add note drag start
-                       } else if (editor.internal_editing()) {
+                } else if (trackview.editor().internal_editing()) {
 
-                               delete _ghost_note;
-                               _ghost_note = 0;
+                        delete _ghost_note;
+                        _ghost_note = 0;
                                
-                               group->grab(GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
-                                               Gdk::Cursor(Gdk::FLEUR), ev->motion.time);
-                               last_x = event_x;
-                               last_y = event_y;
-                               drag_start_x = event_x;
-                               drag_start_y = event_y;
-
-                               drag_rect = new ArdourCanvas::SimpleRect(*group);
-                               drag_rect->property_x1() = trackview.editor().frame_to_pixel(event_frame);
-
-                               drag_rect->property_y1() = midi_stream_view()->note_to_y(
-                                               midi_stream_view()->y_to_note(event_y));
-                               drag_rect->property_x2() = trackview.editor().frame_to_pixel(event_frame);
-                               drag_rect->property_y2() = drag_rect->property_y1()
-                                                        + floor(midi_stream_view()->note_height());
-                               drag_rect->property_outline_what() = 0xFF;
-                               drag_rect->property_outline_color_rgba() = 0xFFFFFF99;
-                               drag_rect->property_fill_color_rgba()    = 0xFFFFFF66;
-
-                               _mouse_state = AddDragging;
-                               return true;
-                       }
+                        group->grab(GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
+                                    Gdk::Cursor(Gdk::FLEUR), ev->time);
+                        _last_x = event_x;
+                        _last_y = event_y;
+                        _drag_start_x = event_x;
+                        _drag_start_y = event_y;
+
+                        _drag_rect = new ArdourCanvas::SimpleRect(*group);
+                        _drag_rect->property_x1() = trackview.editor().frame_to_pixel(event_frame);
+
+                        _drag_rect->property_y1() = midi_stream_view()->note_to_y(
+                                midi_stream_view()->y_to_note(event_y));
+                        _drag_rect->property_x2() = trackview.editor().frame_to_pixel(event_frame);
+                        _drag_rect->property_y2() = _drag_rect->property_y1()
+                                + floor(midi_stream_view()->note_height());
+                        _drag_rect->property_outline_what() = 0xFF;
+                        _drag_rect->property_outline_color_rgba() = 0xFFFFFF99;
+                        _drag_rect->property_fill_color_rgba()    = 0xFFFFFF66;
+
+                        _mouse_state = AddDragging;
+                        return true;
+                }
 
-                       return false;
-
-               case SelectRectDragging: // Select drag motion
-               case AddDragging: // Add note drag motion
-                       if (ev->motion.is_hint) {
-                               int t_x;
-                               int t_y;
-                               GdkModifierType state;
-                               gdk_window_get_pointer(ev->motion.window, &t_x, &t_y, &state);
-                               event_x = t_x;
-                               event_y = t_y;
-                       }
+                return false;
+
+        case SelectRectDragging: // Select drag motion
+        case AddDragging: // Add note drag motion
+                if (ev->is_hint) {
+                        int t_x;
+                        int t_y;
+                        GdkModifierType state;
+                        gdk_window_get_pointer(ev->window, &t_x, &t_y, &state);
+                        event_x = t_x;
+                        event_y = t_y;
+                }
 
-                       if (_mouse_state == AddDragging)
-                               event_x = trackview.editor().frame_to_pixel(event_frame);
+                if (_mouse_state == AddDragging)
+                        event_x = trackview.editor().frame_to_pixel(event_frame);
 
-                       if (drag_rect) {
-                               if (event_x > drag_start_x)
-                                       drag_rect->property_x2() = event_x;
-                               else
-                                       drag_rect->property_x1() = event_x;
-                       }
+                if (_drag_rect) {
+                        if (event_x > _drag_start_x)
+                                _drag_rect->property_x2() = event_x;
+                        else
+                                _drag_rect->property_x1() = event_x;
+                }
 
-                       if (drag_rect && _mouse_state == SelectRectDragging) {
-                               if (event_y > drag_start_y)
-                                       drag_rect->property_y2() = event_y;
-                               else
-                                       drag_rect->property_y1() = event_y;
+                if (_drag_rect && _mouse_state == SelectRectDragging) {
+                        if (event_y > _drag_start_y)
+                                _drag_rect->property_y2() = event_y;
+                        else
+                                _drag_rect->property_y1() = event_y;
 
-                               update_drag_selection(drag_start_x, event_x, drag_start_y, event_y);
-                       }
+                        update_drag_selection(_drag_start_x, event_x, _drag_start_y, event_y);
+                }
 
-                       last_x = event_x;
-                       last_y = event_y;
+                _last_x = event_x;
+                _last_y = event_y;
 
-               case SelectTouchDragging:
-                       return false;
+        case SelectTouchDragging:
+                return false;
 
-               default:
-                       break;
-               }
-               break;
-       }
-
-       case GDK_BUTTON_RELEASE:
-               event_x = ev->motion.x;
-               event_y = ev->motion.y;
-               group->w2i(event_x, event_y);
-               group->ungrab(ev->button.time);
-               event_frame = trackview.editor().pixel_to_frame(event_x);
-
-               if (ev->button.button == 3) {
-                       return false;
-               } else if (_pressed_button != 1) {
-                       return false;
-               }
+        default:
+                break;
+        }
 
-               switch (_mouse_state) {
-               case Pressed: // Clicked
-                       switch (editor.current_mouse_mode()) {
-                       case MouseObject:
-                       case MouseTimeFX:
-                               clear_selection();
-                               break;
-                       case MouseRange:
-                       {
-                               bool success;
-                               Evoral::MusicalTime beats = trackview.editor().get_grid_type_as_beats (success, trackview.editor().pixel_to_frame (event_x));
-                               if (!success) {
-                                       beats = 1;
-                               }
+        return false;
+}
 
-                               create_note_at (event_x, event_y, beats);
-                               break;
-                       }
-                       default:
-                               break;
-                       }
-                       _mouse_state = None;
-                       break;
-               case SelectRectDragging: // Select drag done
-                       _mouse_state = None;
-                       delete drag_rect;
-                       drag_rect = 0;
-                       break;
-               case AddDragging: // Add drag done
-                       _mouse_state = None;
-                       if (drag_rect->property_x2() > drag_rect->property_x1() + 2) {
-                               const double x      = drag_rect->property_x1();
-                               const double length = trackview.editor().pixel_to_frame(
-                                                       drag_rect->property_x2() - drag_rect->property_x1());
-
-                               create_note_at(x, drag_rect->property_y1(), frames_to_beats(length));
-                       }
 
-                       delete drag_rect;
-                       drag_rect = 0;
+bool
+MidiRegionView::scroll (GdkEventScroll* ev)
+{
+        bool fine = Keyboard::modifier_state_equals (ev->state, Keyboard::Level4Modifier);
+        
+        if (ev->direction == GDK_SCROLL_UP) {
+                change_velocities (true, fine, false);
+                return true;
+        } else if (ev->direction == GDK_SCROLL_DOWN) {
+                change_velocities (false, fine, false);
+                return true;
+        } 
+        return false;
+}
 
-                       create_ghost_note (ev->button.x, ev->button.y);
-               default: break;
-               }
-               
-       default: break;
-       }
+bool
+MidiRegionView::key_press (GdkEventKey* ev)
+{ 
+        /* since GTK bindings are generally activated on press, and since
+           detectable auto-repeat is the name of the game and only sends
+           repeated presses, carry out key actions at key press, not release.
+        */
+        
+        if (ev->keyval == GDK_Alt_L || ev->keyval == GDK_Alt_R){
+                _mouse_state = SelectTouchDragging;
+                return true;
+                
+        } else if (ev->keyval == GDK_Escape) {
+                clear_selection();
+                _mouse_state = None;
+                
+        } else if (ev->keyval == GDK_comma || ev->keyval == GDK_period) {
+                
+                bool start = (ev->keyval == GDK_comma);
+                bool end = (ev->keyval == GDK_period);
+                bool shorter = Keyboard::modifier_state_contains (ev->state, Keyboard::PrimaryModifier);
+                bool fine = Keyboard::modifier_state_contains (ev->state, Keyboard::SecondaryModifier);
+                
+                change_note_lengths (fine, shorter, start, end);
+                
+                return true;
+                
+        } else if (ev->keyval == GDK_Delete) {
+                
+                delete_selection();
+                return true;
+                
+        } else if (ev->keyval == GDK_Tab) {
+                
+                if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
+                        goto_previous_note ();
+                } else {
+                        goto_next_note ();
+                }
+                return true;
+                
+        } else if (ev->keyval == GDK_Up) {
+                
+                bool allow_smush = Keyboard::modifier_state_contains (ev->state, Keyboard::SecondaryModifier);
+                bool fine = Keyboard::modifier_state_contains (ev->state, Keyboard::TertiaryModifier);
+                
+                if (Keyboard::modifier_state_contains (ev->state, Keyboard::PrimaryModifier)) {
+                        change_velocities (true, fine, allow_smush);
+                } else {
+                        transpose (true, fine, allow_smush);
+                }
+                return true;
+                
+        } else if (ev->keyval == GDK_Down) {
+                
+                bool allow_smush = Keyboard::modifier_state_contains (ev->state, Keyboard::SecondaryModifier);
+                bool fine = Keyboard::modifier_state_contains (ev->state, Keyboard::TertiaryModifier);
+                
+                if (Keyboard::modifier_state_contains (ev->state, Keyboard::PrimaryModifier)) {
+                        change_velocities (false, fine, allow_smush);
+                } else {
+                        transpose (false, fine, allow_smush);
+                }
+                return true;
+                
+        } else if (ev->keyval == GDK_Left) {
+                
+                nudge_notes (false);
+                return true;
+                
+        } else if (ev->keyval == GDK_Right) {
+                
+                nudge_notes (true);
+                return true;
+                
+        } else if (ev->keyval == GDK_Control_L) {
+                return true;
+                
+        } else if (ev->keyval == GDK_r) {
+                /* if we're not step editing, this really doesn't matter */
+                midi_view()->step_edit_rest ();
+                return true;
+        }
+        
+        return false;
+}
 
-       return false;
+bool
+MidiRegionView::key_release (GdkEventKey* ev)
+{
+        if (ev->keyval == GDK_Alt_L || ev->keyval == GDK_Alt_R) {
+                _mouse_state = None;
+                return true;
+        }
+        return false;
 }
 
 void
index 9950c03f867ea061f8cdf19b036cf90332ece452..f823de2e9a9218f215685d4204025c290aa03c4e 100644 (file)
@@ -372,6 +372,11 @@ class MidiRegionView : public RegionView
        ArdourCanvas::CanvasNote*            _ghost_note;
        double                               _last_ghost_x;
        double                               _last_ghost_y;
+        double                               _drag_start_x;
+        double                               _drag_start_y;
+        double                               _last_x;
+        double                               _last_y;
+       ArdourCanvas::SimpleRect*            _drag_rect;
 
        MouseState _mouse_state;
        int _pressed_button;
@@ -416,6 +421,15 @@ class MidiRegionView : public RegionView
        PBD::ScopedConnection snap_changed_connection;
 
        void show_verbose_canvas_cursor (boost::shared_ptr<NoteType>) const;
+
+        bool motion (GdkEventMotion*);
+        bool scroll (GdkEventScroll*);
+        bool key_press (GdkEventKey*);
+        bool key_release (GdkEventKey*);
+        bool button_press (GdkEventButton*);
+        bool button_release (GdkEventButton*);
+        bool enter_notify (GdkEventCrossing*);
+        bool leave_notify (GdkEventCrossing*);
 };