Split up Editor::button_press_handler and fix assert failures on various double-clicks.
authorCarl Hetherington <carl@carlh.net>
Tue, 4 Aug 2009 18:21:09 +0000 (18:21 +0000)
committerCarl Hetherington <carl@carlh.net>
Tue, 4 Aug 2009 18:21:09 +0000 (18:21 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@5490 d708f5d6-7413-0410-9779-e7cbd77b26cf

gtk2_ardour/editor.h
gtk2_ardour/editor_mouse.cc

index b4ab0898becc3bb9cee2b22fa7ebe603b7b7ddbf..6b6358c2cb04f40943a60ea7ecb8278e15ccbff5 100644 (file)
@@ -1008,6 +1008,8 @@ class Editor : public PublicEditor
 
        bool typed_event (ArdourCanvas::Item*, GdkEvent*, ItemType);
        bool button_press_handler (ArdourCanvas::Item*, GdkEvent*, ItemType);
+       bool button_press_handler_1 (ArdourCanvas::Item *, GdkEvent *, ItemType);
+       bool button_press_handler_2 (ArdourCanvas::Item *, GdkEvent *, ItemType);
        bool button_release_handler (ArdourCanvas::Item*, GdkEvent*, ItemType);
        bool motion_handler (ArdourCanvas::Item*, GdkEvent*, bool from_autoscroll = false);
        bool enter_handler (ArdourCanvas::Item*, GdkEvent*, ItemType);
index 1a0cd75ba2fdc8128947d6d62e23fa24c7b39e4b..02c13fb2516f3bfca7c29b93e740181ef4519f33 100644 (file)
@@ -500,438 +500,288 @@ Editor::button_selection (ArdourCanvas::Item* /*item*/, GdkEvent* event, ItemTyp
 }
 
 bool
-Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_type)
+Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_type)
 {
-       Glib::RefPtr<Gdk::Window> canvas_window = const_cast<Editor*>(this)->track_canvas->get_window();
-
-       if (canvas_window) {
-               Glib::RefPtr<const Gdk::Window> pointer_window;
-               int x, y;
-               double wx, wy;
-               Gdk::ModifierType mask;
-
-               pointer_window = canvas_window->get_pointer (x, y, mask);
+       if (_drag) {
+               _drag->item()->ungrab (event->button.time);
+       }
+       
+       /* single mouse clicks on any of these item types operate
+          independent of mouse mode, mostly because they are
+          not on the main track canvas or because we want
+          them to be modeless.
+       */
+       
+       switch (item_type) {
+       case PlayheadCursorItem:
+               assert (_drag == 0);
+               _drag = new CursorDrag (this, item, true);
+               _drag->start_grab (event);
+               return true;
                
-               if (pointer_window == track_canvas->get_bin_window()) {
-                       track_canvas->window_to_world (x, y, wx, wy);
-                       allow_vertical_scroll = true;
+       case MarkerItem:
+               if (Keyboard::modifier_state_equals (event->button.state, Keyboard::ModifierMask(Keyboard::PrimaryModifier|Keyboard::TertiaryModifier))) {
+                       hide_marker (item, event);
                } else {
-                       allow_vertical_scroll = false;
+                       assert (_drag == 0);
+                       _drag = new MarkerDrag (this, item);
+                       _drag->start_grab (event);
                }
-       }
-
-       track_canvas->grab_focus();
-
-       if (session && session->actively_recording()) {
                return true;
-       }
-
-       button_selection (item, event, item_type);
+               
+       case TempoMarkerItem:
+               assert (_drag == 0);
+               _drag = new TempoMarkerDrag (
+                       this,
+                       item,
+                       Keyboard::modifier_state_contains (event->button.state, Keyboard::CopyModifier)
+                       );
+               _drag->start_grab (event);
+               return true;
+               
+       case MeterMarkerItem:
+               assert (_drag == 0);
+               _drag = new MeterMarkerDrag (
+                       this,
+                       item, 
+                       Keyboard::modifier_state_contains (event->button.state, Keyboard::CopyModifier)
+                       );
+               _drag->start_grab (event);
+               return true;
+               
+       case MarkerBarItem:
+       case TempoBarItem:
+       case MeterBarItem:
+               if (!Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) {
+                       assert (_drag == 0);
+                       _drag = new CursorDrag (this, &playhead_cursor->canvas_item, false);
+                       _drag->start_grab (event);
+               }
+               return true;
+               break;
 
-       if (_drag == 0 &&
-           (Keyboard::is_delete_event (&event->button) ||
-            Keyboard::is_context_menu_event (&event->button) ||
-            Keyboard::is_edit_event (&event->button))) {
+                               
+       case RangeMarkerBarItem:
+               assert (_drag == 0);
+               if (!Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) {
+                       _drag = new CursorDrag (this, &playhead_cursor->canvas_item, false);
+               } else {
+                       _drag = new RangeMarkerBarDrag (this, item, RangeMarkerBarDrag::CreateRangeMarker); 
+               }       
+               _drag->start_grab (event);
+               return true;
+               break;
                
-               /* handled by button release */
+       case CdMarkerBarItem:
+               assert (_drag == 0);
+               if (!Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) {
+                       _drag = new CursorDrag (this, &playhead_cursor->canvas_item, false);
+               } else {
+                       _drag = new RangeMarkerBarDrag (this, item, RangeMarkerBarDrag::CreateCDMarker);
+               }
+               _drag->start_grab (event);
                return true;
+               break;
+               
+       case TransportMarkerBarItem:
+               assert (_drag == 0);
+               if (!Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) {
+                       _drag = new CursorDrag (this, &playhead_cursor->canvas_item, false);
+               } else {
+                       _drag = new RangeMarkerBarDrag (this, item, RangeMarkerBarDrag::CreateTransportMarker);
+               }
+               _drag->start_grab (event);
+               return true;
+               break;
+               
+       default:
+               break;
        }
-
-       switch (event->button.button) {
-       case 1:
-
-               if (event->type == GDK_BUTTON_PRESS) {
-
-                       if (_drag) {
-                               _drag->item()->ungrab (event->button.time);
-                       }
-
-                       /* single mouse clicks on any of these item types operate
-                          independent of mouse mode, mostly because they are
-                          not on the main track canvas or because we want
-                          them to be modeless.
-                       */
-
+       
+       if (internal_editing()) {
+               assert (_drag == 0);
+               _drag = new RegionCreateDrag (this, item, clicked_axisview);
+               _drag->start_grab (event);
+       } else {
+               switch (mouse_mode) {
+               case MouseRange:
                        switch (item_type) {
-                       case PlayheadCursorItem:
+                       case StartSelectionTrimItem:
                                assert (_drag == 0);
-                               _drag = new CursorDrag (this, item, true);
+                               _drag = new SelectionDrag (this, item, SelectionDrag::SelectionStartTrim);
                                _drag->start_grab (event);
-                               return true;
-
-                       case MarkerItem:
-                               if (Keyboard::modifier_state_equals (event->button.state, Keyboard::ModifierMask(Keyboard::PrimaryModifier|Keyboard::TertiaryModifier))) {
-                                       hide_marker (item, event);
-                               } else {
-                                       assert (_drag == 0);
-                                       _drag = new MarkerDrag (this, item);
-                                       _drag->start_grab (event);
-                               }
-                               return true;
-
-                       case TempoMarkerItem:
+                               break;
+                               
+                       case EndSelectionTrimItem:
                                assert (_drag == 0);
-                               _drag = new TempoMarkerDrag (
-                                       this,
-                                       item,
-                                       Keyboard::modifier_state_contains (event->button.state, Keyboard::CopyModifier)
-                                       );
+                               _drag = new SelectionDrag (this, item, SelectionDrag::SelectionEndTrim);
                                _drag->start_grab (event);
-                               return true;
-
-                       case MeterMarkerItem:
-                               assert (_drag == 0);
-
-                               _drag = new MeterMarkerDrag (
-                                       this,
-                                       item, 
-                                       Keyboard::modifier_state_contains (event->button.state, Keyboard::CopyModifier)
-                                       );
+                               break;
                                
-                               _drag->start_grab (event);
-                               return true;
-
-                       case MarkerBarItem:
-                       case TempoBarItem:
-                       case MeterBarItem:
-                               if (!Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) {
+                       case SelectionItem:
+                               if (Keyboard::modifier_state_contains 
+                                   (event->button.state, Keyboard::ModifierMask(Keyboard::SecondaryModifier))) {
+                                       // contains and not equals because I can't use alt as a modifier alone.
+                                       start_selection_grab (item, event);
+                               } else if (Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) {
+                                       /* grab selection for moving */
                                        assert (_drag == 0);
-                                       _drag = new CursorDrag (this, &playhead_cursor->canvas_item, false);
+                                       _drag = new SelectionDrag (this, item, SelectionDrag::SelectionMove);
+                                       _drag->start_grab (event);
+                               } else {
+                                       /* this was debated, but decided the more common action was to
+                                          make a new selection */
+                                       assert (_drag == 0);
+                                       _drag = new SelectionDrag (this, item, SelectionDrag::CreateSelection);
                                        _drag->start_grab (event);
                                }
-                               return true;
                                break;
-
                                
-                       case RangeMarkerBarItem:
+                       default:
                                assert (_drag == 0);
-                               if (!Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) {
-                                       _drag = new CursorDrag (this, &playhead_cursor->canvas_item, false);
-                               } else {
-                                       _drag = new RangeMarkerBarDrag (this, item, RangeMarkerBarDrag::CreateRangeMarker); 
-                               }       
+                               _drag = new SelectionDrag (this, item, SelectionDrag::CreateSelection);
                                _drag->start_grab (event);
-                               return true;
-                               break;
-
-                       case CdMarkerBarItem:
-                               assert (_drag == 0);
-                               if (!Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) {
-                                       _drag = new CursorDrag (this, &playhead_cursor->canvas_item, false);
-                               } else {
-                                       _drag = new RangeMarkerBarDrag (this, item, RangeMarkerBarDrag::CreateCDMarker);
-                               }
-                               _drag->start_grab (event);
-                               return true;
-                               break;
-
-                       case TransportMarkerBarItem:
+                       }
+                       return true;
+                       break;
+                       
+               case MouseObject:
+                       if (Keyboard::modifier_state_contains (event->button.state, Keyboard::ModifierMask(Keyboard::PrimaryModifier|Keyboard::SecondaryModifier)) &&
+                           event->type == GDK_BUTTON_PRESS) {
+                               
                                assert (_drag == 0);
-                               if (!Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) {
-                                       _drag = new CursorDrag (this, &playhead_cursor->canvas_item, false);
-                               } else {
-                                       _drag = new RangeMarkerBarDrag (this, item, RangeMarkerBarDrag::CreateTransportMarker);
-                               }
+                               _drag = new RubberbandSelectDrag (this, item);
                                _drag->start_grab (event);
-                               return true;
-                               break;
                                
-                       default:
-                               break;
-                       }
-               }
-
-               if (internal_editing()) {
-                       assert (_drag == 0);
-                       _drag = new RegionCreateDrag (this, item, clicked_axisview);
-                       _drag->start_grab (event);
-                       cerr << "--- DRAG START FOR RCD\n";
-               } else {
-                       switch (mouse_mode) {
-                       case MouseRange:
+                       } else if (event->type == GDK_BUTTON_PRESS) {
+                               
                                switch (item_type) {
-                               case StartSelectionTrimItem:
+                               case FadeInHandleItem:
+                               {
                                        assert (_drag == 0);
-                                       _drag = new SelectionDrag (this, item, SelectionDrag::SelectionStartTrim);
+                                       RegionSelection s = get_equivalent_regions (selection->regions, RouteGroup::Edit);
+                                       _drag = new FadeInDrag (this, item, reinterpret_cast<RegionView*> (item->get_data("regionview")), s);
                                        _drag->start_grab (event);
-                                       break;
+                                       return true;
+                               }
                                
-                               case EndSelectionTrimItem:
+                               case FadeOutHandleItem:
+                               {
                                        assert (_drag == 0);
-                                       _drag = new SelectionDrag (this, item, SelectionDrag::SelectionEndTrim);
+                                       RegionSelection s = get_equivalent_regions (selection->regions, RouteGroup::Edit);
+                                       _drag = new FadeOutDrag (this, item, reinterpret_cast<RegionView*> (item->get_data("regionview")), s);
                                        _drag->start_grab (event);
-                                       break;
-
-                               case SelectionItem:
-                                       if (Keyboard::modifier_state_contains 
-                                           (event->button.state, Keyboard::ModifierMask(Keyboard::SecondaryModifier))) {
-                                               // contains and not equals because I can't use alt as a modifier alone.
-                                               start_selection_grab (item, event);
-                                       } else if (Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) {
-                                               /* grab selection for moving */
-                                               assert (_drag == 0);
-                                               _drag = new SelectionDrag (this, item, SelectionDrag::SelectionMove);
-                                               _drag->start_grab (event);
+                                       return true;
+                               }
+                               
+                               case RegionItem:
+                                       if (Keyboard::modifier_state_contains (event->button.state, Keyboard::CopyModifier)) {
+                                               start_region_copy_grab (item, event, clicked_regionview);
+                                       } else if (Keyboard::the_keyboard().key_is_down (GDK_b)) {
+                                               start_region_brush_grab (item, event, clicked_regionview);
                                        } else {
-                                               /* this was debated, but decided the more common action was to
-                                                  make a new selection */
-                                               assert (_drag == 0);
-                                               _drag = new SelectionDrag (this, item, SelectionDrag::CreateSelection);
-                                               _drag->start_grab (event);
+                                               start_region_grab (item, event, clicked_regionview);
                                        }
                                        break;
-
-                               default:
-                                       assert (_drag == 0);
-                                       _drag = new SelectionDrag (this, item, SelectionDrag::CreateSelection);
-                                       _drag->start_grab (event);
-                               }
-                               return true;
-                               break;
-                       
-                       case MouseObject:
-                               if (Keyboard::modifier_state_contains (event->button.state, Keyboard::ModifierMask(Keyboard::PrimaryModifier|Keyboard::SecondaryModifier)) &&
-                                   event->type == GDK_BUTTON_PRESS) {
-
-                                       assert (_drag == 0);
-                                       _drag = new RubberbandSelectDrag (this, item);
-                                       _drag->start_grab (event);
-
-                               } else if (event->type == GDK_BUTTON_PRESS) {
-
-                                       switch (item_type) {
-                                       case FadeInHandleItem:
-                                       {
-                                               assert (_drag == 0);
-                                               RegionSelection s = get_equivalent_regions (selection->regions, RouteGroup::Edit);
-                                               _drag = new FadeInDrag (this, item, reinterpret_cast<RegionView*> (item->get_data("regionview")), s);
-                                               _drag->start_grab (event);
-                                               return true;
-                                       }
-                                       
-                                       case FadeOutHandleItem:
-                                       {
-                                               assert (_drag == 0);
-                                               RegionSelection s = get_equivalent_regions (selection->regions, RouteGroup::Edit);
-                                               _drag = new FadeOutDrag (this, item, reinterpret_cast<RegionView*> (item->get_data("regionview")), s);
-                                               _drag->start_grab (event);
-                                               return true;
-                                       }
-
-                                       case RegionItem:
-                                               if (Keyboard::modifier_state_contains (event->button.state, Keyboard::CopyModifier)) {
-                                                       start_region_copy_grab (item, event, clicked_regionview);
-                                               } else if (Keyboard::the_keyboard().key_is_down (GDK_b)) {
-                                                       start_region_brush_grab (item, event, clicked_regionview);
-                                               } else {
-                                                       start_region_grab (item, event, clicked_regionview);
-                                               }
-                                               break;
                                        
-                                       case RegionViewNameHighlight:
-                                       {
-                                               assert (_drag == 0);
-                                               RegionSelection s = get_equivalent_regions (selection->regions, RouteGroup::Edit);
-                                               _drag = new TrimDrag (this, item, clicked_regionview, s.by_layer());
-                                               _drag->start_grab (event);
-                                               return true;
-                                               break;
-                                       }
-                                       
-                                       case RegionViewName:
-                                       {
-                                               /* rename happens on edit clicks */
-                                               assert (_drag == 0);
-                                               RegionSelection s = get_equivalent_regions (selection->regions, RouteGroup::Edit);
-                                               _drag = new TrimDrag (this, clicked_regionview->get_name_highlight(), clicked_regionview, s.by_layer());
-                                               _drag->start_grab (event);
-                                               return true;
-                                               break;
-                                       }
-
-                                       case ControlPointItem:
-                                               assert (_drag == 0);
-                                               _drag = new ControlPointDrag (this, item);
-                                               _drag->start_grab (event);
-                                               return true;
-                                               break;
-                                       
-                                       case AutomationLineItem:
-                                               assert (_drag == 0);
-                                               _drag = new LineDrag (this, item);
-                                               _drag->start_grab (event);
-                                               return true;
-                                               break;
-
-                                       case StreamItem:
-                                       case AutomationTrackItem:
-                                               assert (_drag == 0);
-                                               _drag = new RubberbandSelectDrag (this, item);
-                                               _drag->start_grab (event);
-                                               break;
-                                       
-#ifdef WITH_CMT
-                                       case ImageFrameHandleStartItem:
-                                               imageframe_start_handle_op(item, event) ;
-                                               return(true) ;
-                                               break ;
-                                       case ImageFrameHandleEndItem:
-                                               imageframe_end_handle_op(item, event) ;
-                                               return(true) ;
-                                               break ;
-                                       case MarkerViewHandleStartItem:
-                                               markerview_item_start_handle_op(item, event) ;
-                                               return(true) ;
-                                               break ;
-                                       case MarkerViewHandleEndItem:
-                                               markerview_item_end_handle_op(item, event) ;
-                                               return(true) ;
-                                               break ;
-                                       case MarkerViewItem:
-                                               start_markerview_grab(item, event) ;
-                                               break ;
-                                       case ImageFrameItem:
-                                               start_imageframe_grab(item, event) ;
-                                               break ;
-#endif
-
-                                       case MarkerBarItem:
-                                       
-                                               break;
-
-                                       default:
-                                               break;
-                                       }
-                               }
-                               return true;
-                               break;
-                       
-                       case MouseGain:
-                               switch (item_type) {
-                               case RegionItem:
-                                       /* start a grab so that if we finish after moving
-                                          we can tell what happened.
-                                       */
-                                       assert (_drag == 0);
-                                       _drag = new RegionGainDrag (this, item);
-                                       _drag->start_grab (event, current_canvas_cursor);
-                                       break;
-
-                               case GainLineItem:
+                               case RegionViewNameHighlight:
+                               {
                                        assert (_drag == 0);
-                                       _drag = new LineDrag (this, item);
+                                       RegionSelection s = get_equivalent_regions (selection->regions, RouteGroup::Edit);
+                                       _drag = new TrimDrag (this, item, clicked_regionview, s.by_layer());
                                        _drag->start_grab (event);
                                        return true;
-
-                               case ControlPointItem:
+                                       break;
+                               }
+                               
+                               case RegionViewName:
+                               {
+                                       /* rename happens on edit clicks */
                                        assert (_drag == 0);
-                                       _drag = new ControlPointDrag (this, item);
+                                       RegionSelection s = get_equivalent_regions (selection->regions, RouteGroup::Edit);
+                                       _drag = new TrimDrag (this, clicked_regionview->get_name_highlight(), clicked_regionview, s.by_layer());
                                        _drag->start_grab (event);
                                        return true;
                                        break;
-
-                               default:
-                                       break;
                                }
-                               return true;
-                               break;
-
-                               switch (item_type) {
+                               
                                case ControlPointItem:
                                        assert (_drag == 0);
                                        _drag = new ControlPointDrag (this, item);
                                        _drag->start_grab (event);
+                                       return true;
                                        break;
-
+                                       
                                case AutomationLineItem:
                                        assert (_drag == 0);
                                        _drag = new LineDrag (this, item);
                                        _drag->start_grab (event);
+                                       return true;
                                        break;
 
-                               case RegionItem:
-                                       // XXX need automation mode to identify which
-                                       // line to use
-                                       // start_line_grab_from_regionview (item, event);
-                                       break;
-
-                               default:
-                                       break;
-                               }
-                               return true;
-                               break;
-
-                       case MouseZoom:
-                               if (event->type == GDK_BUTTON_PRESS) {
+                               case StreamItem:
+                               case AutomationTrackItem:
                                        assert (_drag == 0);
-                                       _drag = new MouseZoomDrag (this, item);
-                                       _drag->start_grab (event);
-                               }
-
-                               return true;
-                               break;
-
-                       case MouseTimeFX:
-                               if (item_type == RegionItem) {
-                                       assert (_drag == 0);
-                                       _drag = new TimeFXDrag (this, item, clicked_regionview, selection->regions.by_layer());
+                                       _drag = new RubberbandSelectDrag (this, item);
                                        _drag->start_grab (event);
-                               }
-                               break;
-
-                       case MouseAudition:
-                               _drag = new ScrubDrag (this, item);
-                               _drag->start_grab (event);
-                               scrub_reversals = 0;
-                               scrub_reverse_distance = 0;
-                               last_scrub_x = event->button.x;
-                               scrubbing_direction = 0;
-                               track_canvas->get_window()->set_cursor (*transparent_cursor);
-                               break;
-
-                       default:
-                               break;
-                       }
-               }
-               break;
-
-       case 2:
-               switch (mouse_mode) {
-               case MouseObject:
-                       if (event->type == GDK_BUTTON_PRESS) {
-                               switch (item_type) {
-                               case RegionItem:
-                                       if (Keyboard::modifier_state_contains (event->button.state, Keyboard::CopyModifier)) {
-                                               start_region_copy_grab (item, event, clicked_regionview);
-                                       } else {
-                                               start_region_grab (item, event, clicked_regionview);
-                                       }
-                                       return true;
                                        break;
-                               case ControlPointItem:
-                                       assert (_drag == 0);
-                                       _drag = new ControlPointDrag (this, item);
-                                       _drag->start_grab (event);
-                                       return true;
+                                       
+#ifdef WITH_CMT
+                               case ImageFrameHandleStartItem:
+                                       imageframe_start_handle_op(item, event) ;
+                                       return(true) ;
+                                       break ;
+                               case ImageFrameHandleEndItem:
+                                       imageframe_end_handle_op(item, event) ;
+                                       return(true) ;
+                                       break ;
+                               case MarkerViewHandleStartItem:
+                                       markerview_item_start_handle_op(item, event) ;
+                                       return(true) ;
+                                       break ;
+                               case MarkerViewHandleEndItem:
+                                       markerview_item_end_handle_op(item, event) ;
+                                       return(true) ;
+                                       break ;
+                               case MarkerViewItem:
+                                       start_markerview_grab(item, event) ;
+                                       break ;
+                               case ImageFrameItem:
+                                       start_imageframe_grab(item, event) ;
+                                       break ;
+#endif
+                                       
+                               case MarkerBarItem:
+                                       
                                        break;
                                        
                                default:
                                        break;
                                }
                        }
+                       return true;
+                       break;
                        
-                       
+               case MouseGain:
                        switch (item_type) {
-                       case RegionViewNameHighlight:
+                       case RegionItem:
+                               /* start a grab so that if we finish after moving
+                                  we can tell what happened.
+                               */
                                assert (_drag == 0);
-                               _drag = new TrimDrag (this, item, clicked_regionview, selection->regions.by_layer());
+                               _drag = new RegionGainDrag (this, item);
+                               _drag->start_grab (event, current_canvas_cursor);
+                               break;
+                               
+                       case GainLineItem:
+                               assert (_drag == 0);
+                               _drag = new LineDrag (this, item);
                                _drag->start_grab (event);
                                return true;
-                               break;
                                
-                       case RegionViewName:
+                       case ControlPointItem:
                                assert (_drag == 0);
-                               _drag = new TrimDrag (this, clicked_regionview->get_name_highlight(), clicked_regionview, selection->regions.by_layer());
+                               _drag = new ControlPointDrag (this, item);
                                _drag->start_grab (event);
                                return true;
                                break;
@@ -939,30 +789,187 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp
                        default:
                                break;
                        }
+                       return true;
+                       break;
                        
+                       switch (item_type) {
+                       case ControlPointItem:
+                               assert (_drag == 0);
+                               _drag = new ControlPointDrag (this, item);
+                               _drag->start_grab (event);
+                               break;
+                               
+                       case AutomationLineItem:
+                               assert (_drag == 0);
+                               _drag = new LineDrag (this, item);
+                               _drag->start_grab (event);
+                               break;
+                               
+                       case RegionItem:
+                               // XXX need automation mode to identify which
+                               // line to use
+                               // start_line_grab_from_regionview (item, event);
+                               break;
+                               
+                       default:
+                               break;
+                       }
+                       return true;
                        break;
-
-               case MouseRange:
+                       
+               case MouseZoom:
                        if (event->type == GDK_BUTTON_PRESS) {
-                               /* relax till release */
+                               assert (_drag == 0);
+                               _drag = new MouseZoomDrag (this, item);
+                               _drag->start_grab (event);
                        }
+                       
                        return true;
                        break;
-                                       
-                               
-               case MouseZoom:
-                       if (Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) {
-                               temporal_zoom_session();
+                       
+               case MouseTimeFX:
+                       if (item_type == RegionItem) {
+                               assert (_drag == 0);
+                               _drag = new TimeFXDrag (this, item, clicked_regionview, selection->regions.by_layer());
+                               _drag->start_grab (event);
+                       }
+                       break;
+                       
+               case MouseAudition:
+                       _drag = new ScrubDrag (this, item);
+                       _drag->start_grab (event);
+                       scrub_reversals = 0;
+                       scrub_reverse_distance = 0;
+                       last_scrub_x = event->button.x;
+                       scrubbing_direction = 0;
+                       track_canvas->get_window()->set_cursor (*transparent_cursor);
+                       break;
+                       
+               default:
+                       break;
+               }
+       }
+
+       return false;
+}
+
+bool
+Editor::button_press_handler_2 (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_type)
+{
+       switch (mouse_mode) {
+       case MouseObject:
+               switch (item_type) {
+               case RegionItem:
+                       if (Keyboard::modifier_state_contains (event->button.state, Keyboard::CopyModifier)) {
+                               start_region_copy_grab (item, event, clicked_regionview);
                        } else {
-                               temporal_zoom_to_frame (true, event_frame(event));
+                               start_region_grab (item, event, clicked_regionview);
                        }
                        return true;
                        break;
-
+               case ControlPointItem:
+                       assert (_drag == 0);
+                       _drag = new ControlPointDrag (this, item);
+                       _drag->start_grab (event);
+                       return true;
+                       break;
+                       
+               default:
+                       break;
+               }
+                       
+               switch (item_type) {
+               case RegionViewNameHighlight:
+                       assert (_drag == 0);
+                       _drag = new TrimDrag (this, item, clicked_regionview, selection->regions.by_layer());
+                       _drag->start_grab (event);
+                       return true;
+                       break;
+                       
+               case RegionViewName:
+                       assert (_drag == 0);
+                       _drag = new TrimDrag (this, clicked_regionview->get_name_highlight(), clicked_regionview, selection->regions.by_layer());
+                       _drag->start_grab (event);
+                       return true;
+                       break;
+                       
                default:
                        break;
                }
+               
+               break;
 
+       case MouseRange:
+               /* relax till release */
+               return true;
+               break;
+               
+               
+       case MouseZoom:
+               if (Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) {
+                       temporal_zoom_session();
+               } else {
+                       temporal_zoom_to_frame (true, event_frame(event));
+               }
+               return true;
+               break;
+               
+       default:
+               break;
+       }
+
+       return false;
+}
+
+bool
+Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_type)
+{
+       if (event->type != GDK_BUTTON_PRESS) {
+               return false;
+       }
+       
+       Glib::RefPtr<Gdk::Window> canvas_window = const_cast<Editor*>(this)->track_canvas->get_window();
+
+       if (canvas_window) {
+               Glib::RefPtr<const Gdk::Window> pointer_window;
+               int x, y;
+               double wx, wy;
+               Gdk::ModifierType mask;
+
+               pointer_window = canvas_window->get_pointer (x, y, mask);
+               
+               if (pointer_window == track_canvas->get_bin_window()) {
+                       track_canvas->window_to_world (x, y, wx, wy);
+                       allow_vertical_scroll = true;
+               } else {
+                       allow_vertical_scroll = false;
+               }
+       }
+
+       track_canvas->grab_focus();
+
+       if (session && session->actively_recording()) {
+               return true;
+       }
+
+       button_selection (item, event, item_type);
+
+       if (_drag == 0 &&
+           (Keyboard::is_delete_event (&event->button) ||
+            Keyboard::is_context_menu_event (&event->button) ||
+            Keyboard::is_edit_event (&event->button))) {
+               
+               /* handled by button release */
+               return true;
+       }
+
+       switch (event->button.button) {
+       case 1:
+               return button_press_handler_1 (item, event, item_type);
+               break;
+
+       case 2:
+               return button_press_handler_2 (item, event, item_type);
                break;
 
        case 3: