new mouse mode (Draw (notes)); switch into internal mode when draw is selected; notab...
[ardour.git] / gtk2_ardour / editor_mouse.cc
index 6419591716fea2211bbe49e3e8f29a677287c975..1e801f16a37e51cd5c7330e58c96784862207771 100644 (file)
@@ -179,7 +179,7 @@ Editor::which_grabber_cursor ()
 
        if (_internal_editing) {
                switch (mouse_mode) {
-               case MouseRange:
+               case MouseDraw:
                        c = _cursors->midi_pencil;
                        break;
 
@@ -241,7 +241,7 @@ Editor::set_canvas_cursor ()
        if (_internal_editing) {
 
                switch (mouse_mode) {
-               case MouseRange:
+               case MouseDraw:
                        current_canvas_cursor = _cursors->midi_pencil;
                        break;
 
@@ -268,6 +268,11 @@ Editor::set_canvas_cursor ()
                        current_canvas_cursor = which_grabber_cursor();
                        break;
 
+               case MouseDraw:
+                       /* shouldn't be possible, but just cover it anyway ... */
+                       current_canvas_cursor = _cursors->midi_pencil;
+                       break;
+
                case MouseGain:
                        current_canvas_cursor = _cursors->cross_hair;
                        break;
@@ -302,8 +307,11 @@ Editor::set_canvas_cursor ()
        }
 
        /* up-down cursor as a cue that automation can be dragged up and down when in join object/range mode */
-       if (join_object_range_button.get_active() && last_item_entered) {
-               if (last_item_entered->property_parent() && (*last_item_entered->property_parent()).get_data (X_("timeselection"))) {
+       if (join_object_range_button.get_active()) {
+               double x, y;
+               get_pointer_position (x, y);
+               ArdourCanvas::Item* i = track_canvas->get_item_at (x, y);
+               if (i && i->property_parent() && (*i->property_parent()).get_data (X_("timeselection"))) {
                        pair<TimeAxisView*, int> tvp = trackview_by_y_position (_last_motion_y + vertical_adjustment.get_value() - canvas_timebars_vsize);
                        if (dynamic_cast<AutomationTimeAxisView*> (tvp.first)) {
                                current_canvas_cursor = _cursors->up_down;
@@ -336,6 +344,10 @@ Editor::set_mouse_mode (MouseMode m, bool force)
                act = ActionManager::get_action (X_("MouseMode"), X_("set-mouse-mode-object"));
                break;
 
+       case MouseDraw:
+               act = ActionManager::get_action (X_("MouseMode"), X_("set-mouse-mode-draw"));
+               break;
+
        case MouseGain:
                act = ActionManager::get_action (X_("MouseMode"), X_("set-mouse-mode-gain"));
                break;
@@ -368,6 +380,62 @@ Editor::set_mouse_mode (MouseMode m, bool force)
 void
 Editor::mouse_mode_toggled (MouseMode m)
 {
+       Glib::RefPtr<Action> act;
+       Glib::RefPtr<ToggleAction> tact;
+
+       switch (m) {
+       case MouseRange:
+               act = ActionManager::get_action (X_("MouseMode"), X_("set-mouse-mode-range"));
+               break;
+
+       case MouseObject:
+               act = ActionManager::get_action (X_("MouseMode"), X_("set-mouse-mode-object"));
+               break;
+
+       case MouseDraw:
+               act = ActionManager::get_action (X_("MouseMode"), X_("set-mouse-mode-draw"));
+               break;
+
+       case MouseGain:
+               act = ActionManager::get_action (X_("MouseMode"), X_("set-mouse-mode-gain"));
+               break;
+
+       case MouseZoom:
+               act = ActionManager::get_action (X_("MouseMode"), X_("set-mouse-mode-zoom"));
+               break;
+
+       case MouseTimeFX:
+               act = ActionManager::get_action (X_("MouseMode"), X_("set-mouse-mode-timefx"));
+               break;
+
+       case MouseAudition:
+               act = ActionManager::get_action (X_("MouseMode"), X_("set-mouse-mode-audition"));
+               break;
+       }
+
+       assert (act);
+
+       tact = Glib::RefPtr<ToggleAction>::cast_dynamic (act);
+       assert (tact);
+
+       if (!tact->get_active()) {
+               /* this was just the notification that the old mode has been
+                * left. we'll get called again with the new mode active in a
+                * jiffy.
+                */
+               return;
+       }
+
+       switch (m) {
+       case MouseDraw:
+               act = ActionManager::get_action (X_("MouseMode"), X_("toggle-internal-edit"));
+               tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
+               tact->set_active (true);
+               break;
+       default:
+               break;
+       }
+
        mouse_mode = m;
 
        instant_save ();
@@ -417,10 +485,15 @@ Editor::step_mouse_mode (bool next)
                break;
 
        case MouseRange:
-               if (next) set_mouse_mode (MouseZoom);
+               if (next) set_mouse_mode (MouseDraw);
                else set_mouse_mode (MouseObject);
                break;
 
+       case MouseDraw:
+               if (next) set_mouse_mode (MouseZoom);
+               else set_mouse_mode (MouseRange);
+               break;
+
        case MouseZoom:
                if (next) {
                        if (Profile->get_sae()) {
@@ -432,7 +505,7 @@ Editor::step_mouse_mode (bool next)
                        if (Profile->get_sae()) {
                                set_mouse_mode (MouseObject);
                        } else {
-                               set_mouse_mode (MouseRange);
+                               set_mouse_mode (MouseDraw);
                        }
                }
                break;
@@ -482,7 +555,8 @@ Editor::button_selection (ArdourCanvas::Item* /*item*/, GdkEvent* event, ItemTyp
             (mouse_mode != MouseAudition || item_type != RegionItem) &&
             (mouse_mode != MouseTimeFX || item_type != RegionItem) &&
             (mouse_mode != MouseGain) &&
-            (mouse_mode != MouseRange)) ||
+            (mouse_mode != MouseRange) &&
+            (mouse_mode != MouseDraw)) ||
            ((event->type != GDK_BUTTON_PRESS && event->type != GDK_BUTTON_RELEASE) || event->button.button > 3) ||
            internal_editing()) {
 
@@ -508,7 +582,7 @@ Editor::button_selection (ArdourCanvas::Item* /*item*/, GdkEvent* event, ItemTyp
        case RegionItem:
                if (mouse_mode != MouseRange || _join_object_range_state == JOIN_OBJECT_RANGE_OBJECT) {
                        set_selected_regionview_from_click (press, op, true);
-               } else if (event->type == GDK_BUTTON_PRESS) {
+               } else if (press) {
                        selection->clear_tracks ();
                        set_selected_track_as_side_effect (op, true);
                }
@@ -792,7 +866,7 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
                if (Keyboard::modifier_state_contains (event->button.state, Keyboard::ModifierMask(Keyboard::PrimaryModifier|Keyboard::SecondaryModifier)) &&
                    event->type == GDK_BUTTON_PRESS) {
 
-                       _drags->set (new RubberbandSelectDrag (this, item), event);
+                       _drags->set (new EditorRubberbandSelectDrag (this, item), event);
 
                } else if (event->type == GDK_BUTTON_PRESS) {
 
@@ -832,7 +906,10 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
                                }
 
                                if (internal_editing ()) {
-                                       /* no region drags in internal edit mode */
+                                       if (event->type == GDK_2BUTTON_PRESS && event->button.button == 1) {
+                                               Glib::RefPtr<Action> act = ActionManager::get_action (X_("MouseMode"), X_("toggle-internal-edit"));
+                                               act->activate ();
+                                       }
                                        break;
                                }
 
@@ -845,7 +922,7 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
                                        add_region_drag (item, event, clicked_regionview);
                                }
 
-                               if (_join_object_range_state == JOIN_OBJECT_RANGE_OBJECT && !selection->regions.empty()) {
+                               if (!internal_editing() && (_join_object_range_state == JOIN_OBJECT_RANGE_OBJECT && !selection->regions.empty())) {
                                        _drags->add (new SelectionDrag (this, clicked_axisview->get_selection_rect (clicked_selection)->rect, SelectionDrag::SelectionMove));
                                }
 
@@ -888,7 +965,7 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
                                        }
                                        return true;
                                } else {
-                                       _drags->set (new RubberbandSelectDrag (this, item), event);
+                                       _drags->set (new EditorRubberbandSelectDrag (this, item), event);
                                }
                                break;
 
@@ -902,7 +979,7 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
                                        _drags->set (new RegionCreateDrag (this, item, parent), event);
                                } else {
                                        /* rubberband drag to select automation points */
-                                       _drags->set (new RubberbandSelectDrag (this, item), event);
+                                       _drags->set (new EditorRubberbandSelectDrag (this, item), event);
                                }
                                break;
                        }
@@ -1121,6 +1198,9 @@ Editor::button_press_handler_2 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
 
                break;
 
+       case MouseDraw:
+               return false;
+
        case MouseRange:
                /* relax till release */
                return true;
@@ -1143,6 +1223,22 @@ Editor::button_press_handler_2 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
        return false;
 }
 
+bool
+Editor::toggle_internal_editing_from_double_click (GdkEvent* event)
+{
+       if (_drags->active()) {
+               _drags->end_grab (event);
+       } 
+       Glib::RefPtr<Action> act = ActionManager::get_action (X_("MouseMode"), X_("toggle-internal-edit"));
+       act->activate ();
+
+       /* prevent reversion of edit cursor on button release */
+       
+       pre_press_cursor = 0;
+
+       return true;
+}
+
 bool
 Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_type)
 {
@@ -1166,7 +1262,7 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp
        }
 
         pre_press_cursor = current_canvas_cursor;
-
+       
        track_canvas->grab_focus();
 
        if (_session && _session->actively_recording()) {
@@ -1297,6 +1393,8 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT
 
        if (Keyboard::is_context_menu_event (&event->button)) {
 
+               context_click_event = *event;
+
                if (!_drags->active ()) {
 
                        /* no matter which button pops up the context menu, tell the menu
@@ -1474,7 +1572,7 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT
                        case AutomationTrackItem:
                                atv = dynamic_cast<AutomationTimeAxisView*>(clicked_axisview);
                                if (atv) {
-                                       atv->add_automation_event (item, event, where, event->button.y);
+                                       atv->add_automation_event (event, where, event->button.y);
                                }
                                return true;
                                break;
@@ -1502,7 +1600,7 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT
 
                        case AutomationTrackItem:
                                dynamic_cast<AutomationTimeAxisView*>(clicked_axisview)->
-                                       add_automation_event (item, event, where, event->button.y);
+                                       add_automation_event (event, where, event->button.y);
                                return true;
                                break;
                        default:
@@ -1560,8 +1658,10 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT
                        }
                        break;
 
+               case MouseDraw:
+                       return true;
+                       
                case MouseRange:
-
                        // x_style_paste (where, 1.0);
                        return true;
                        break;
@@ -1590,8 +1690,6 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
        double fraction;
         bool ret = true;
 
-       last_item_entered = item;
-
        switch (item_type) {
        case ControlPointItem:
                if (mouse_mode == MouseGain || mouse_mode == MouseObject) {
@@ -2551,12 +2649,8 @@ void
 Editor::set_internal_edit (bool yn)
 {
        _internal_editing = yn;
-
+       
        if (yn) {
-               mouse_select_button.set_image (::get_icon("midi_tool_pencil"));
-               ARDOUR_UI::instance()->set_tip (mouse_select_button, _("Draw/Edit MIDI Notes"));
-               mouse_mode_toggled (mouse_mode);
-
                 pre_internal_mouse_mode = mouse_mode;
 
                 for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
@@ -2564,20 +2658,17 @@ Editor::set_internal_edit (bool yn)
                 }
 
        } else {
-
-               mouse_select_button.set_image (::get_icon("tool_range"));
-               ARDOUR_UI::instance()->set_tip (mouse_select_button, _("Select/Move Ranges"));
-               mouse_mode_toggled (mouse_mode); // sets cursor
-
                 for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
                         (*i)->leave_internal_edit_mode ();
                 }
 
-                if (mouse_mode == MouseRange && pre_internal_mouse_mode != MouseRange) {
+                if (mouse_mode == MouseDraw && pre_internal_mouse_mode != MouseDraw) {
                         /* we were drawing .. flip back to something sensible */
                         set_mouse_mode (pre_internal_mouse_mode);
                 }
        }
+       
+       set_canvas_cursor ();
 }
 
 /** Update _join_object_range_state which indicate whether we are over the top or bottom half of a region view,