more MIDI binding map syntax corrections
[ardour.git] / gtk2_ardour / editor_mouse.cc
index a857ca4cec333ca9e48d8368f5c137b8b4000826..9c1b764985e4e840b9807795bfb796cd03fa593a 100644 (file)
 
 #include "pbd/error.h"
 #include "pbd/enumwriter.h"
-#include <gtkmm2ext/utils.h>
-#include <gtkmm2ext/tearoff.h>
 #include "pbd/memento_command.h"
 #include "pbd/basename.h"
 #include "pbd/stateful_diff_command.h"
 
+#include "gtkmm2ext/bindings.h"
+#include "gtkmm2ext/utils.h"
+#include "gtkmm2ext/tearoff.h"
+
 #include "ardour_ui.h"
 #include "actions.h"
 #include "canvas-note.h"
@@ -74,6 +76,7 @@
 #include "ardour/region_factory.h"
 #include "ardour/source_factory.h"
 #include "ardour/session.h"
+#include "ardour/operations.h"
 
 #include <bitset>
 
@@ -377,9 +380,6 @@ Editor::mouse_mode_toggled (MouseMode m)
                           show the object (region) selection.
                        */
                         
-                       for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
-                               (*i)->set_should_show_selection (true);
-                       }
                        for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
                                (*i)->hide_selection ();
                        }
@@ -505,8 +505,6 @@ Editor::button_selection (ArdourCanvas::Item* /*item*/, GdkEvent* event, ItemTyp
        Selection::Operation op = ArdourKeyboard::selection_type (event->button.state);
        bool press = (event->type == GDK_BUTTON_PRESS);
 
-       // begin_reversible_command (_("select on click"));
-
        switch (item_type) {
        case RegionItem:
                if (mouse_mode != MouseRange || _join_object_range_state == JOIN_OBJECT_RANGE_OBJECT) {
@@ -713,8 +711,7 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
                        if (internal_editing()) {
                                /* trim notes if we're in internal edit mode and near the ends of the note */
                                ArdourCanvas::CanvasNote* cn = dynamic_cast<ArdourCanvas::CanvasNote*> (item);
-                               cerr << "NoteItem button press, cursor = " << current_canvas_cursor << endl;
-                               if (cn->mouse_near_ends()) {
+                               if (cn->big_enough_to_trim() && cn->mouse_near_ends()) {
                                        _drags->set (new NoteResizeDrag (this, item), event, current_canvas_cursor);
                                } else {
                                        _drags->set (new NoteDrag (this, item), event);
@@ -735,9 +732,16 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
                        break;
 
                case RegionViewNameHighlight:
+                       if (!clicked_regionview->region()->locked()) {
+                               RegionSelection s = get_equivalent_regions (selection->regions, Properties::edit.property_id);
+                               _drags->set (new TrimDrag (this, item, clicked_regionview, s.by_layer()), event);
+                               return true;
+                       }
+                       break;
+
                case LeftFrameHandle:
                case RightFrameHandle:
-                       if (!clicked_regionview->region()->locked()) {
+                       if (!internal_editing() && !clicked_regionview->region()->locked()) {
                                RegionSelection s = get_equivalent_regions (selection->regions, Properties::edit.property_id);
                                _drags->set (new TrimDrag (this, item, clicked_regionview, s.by_layer()), event);
                                return true;
@@ -820,8 +824,7 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
                                /* click on a normal region view */
                                if (Keyboard::modifier_state_contains (event->button.state, Keyboard::CopyModifier)) {
                                        add_region_copy_drag (item, event, clicked_regionview);
-                               } 
-                               else if (Keyboard::the_keyboard().key_is_down (GDK_b)) {
+                               } else if (Keyboard::the_keyboard().key_is_down (GDK_b)) {
                                        add_region_brush_drag (item, event, clicked_regionview);
                                } else {
                                        add_region_drag (item, event, clicked_regionview);
@@ -837,7 +840,7 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
                        case RegionViewNameHighlight:
                        case LeftFrameHandle:
                         case RightFrameHandle:
-                               if (!internal_editing () && !clicked_regionview->region()->locked()) {
+                               if (!clicked_regionview->region()->locked()) {
                                        RegionSelection s = get_equivalent_regions (selection->regions, Properties::edit.property_id);
                                        _drags->set (new TrimDrag (this, item, clicked_regionview, s.by_layer()), event);
                                        return true;
@@ -1046,6 +1049,11 @@ Editor::button_press_handler_2 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
        case MouseObject:
                switch (item_type) {
                case RegionItem:
+                       if (internal_editing ()) {
+                               /* no region drags in internal edit mode */
+                               return false;
+                       }
+                       
                        if (Keyboard::modifier_state_contains (event->button.state, Keyboard::CopyModifier)) {
                                add_region_copy_drag (item, event, clicked_regionview);
                        } else {
@@ -1065,6 +1073,10 @@ Editor::button_press_handler_2 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
 
                switch (item_type) {
                case RegionViewNameHighlight:
+                        _drags->set (new TrimDrag (this, item, clicked_regionview, selection->regions.by_layer()), event);
+                        return true;
+                        break;
+
                 case LeftFrameHandle:
                 case RightFrameHandle:
                        if (!internal_editing ()) {
@@ -1092,7 +1104,7 @@ Editor::button_press_handler_2 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
 
        case MouseZoom:
                if (Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) {
-                       temporal_zoom_session();
+                       temporal_zoom_to_frame (false, event_frame (event));
                } else {
                        temporal_zoom_to_frame (true, event_frame(event));
                }
@@ -1160,6 +1172,7 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp
                break;
 
        default:
+                return button_press_dispatch (&event->button);
                break;
 
        }
@@ -1167,6 +1180,26 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp
        return false;
 }
 
+bool
+Editor::button_press_dispatch (GdkEventButton* ev)
+{
+        /* this function is intended only for buttons 4 and above.
+         */
+
+        Gtkmm2ext::MouseButton b (ev->state, ev->button);
+        return button_bindings->activate (b, Gtkmm2ext::Bindings::Press);
+}
+
+bool
+Editor::button_release_dispatch (GdkEventButton* ev)
+{
+        /* this function is intended only for buttons 4 and above.
+         */
+
+        Gtkmm2ext::MouseButton b (ev->state, ev->button);
+        return button_bindings->activate (b, Gtkmm2ext::Bindings::Release);
+}
+
 bool
 Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_type)
 {
@@ -1453,7 +1486,7 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT
                        break;
 
                case MouseAudition:
-                        set_canvas_cursor (current_canvas_cursor);
+                       set_canvas_cursor (current_canvas_cursor);
                        if (scrubbing_direction == 0) {
                                /* no drag, just a click */
                                switch (item_type) {
@@ -1471,9 +1504,11 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT
 
                default:
                        break;
-
+                        
                }
 
+                /* do any (de)selection operations that should occur on button release */
+                button_selection (item, event, item_type);
                return true;
                break;
 
@@ -1518,6 +1553,7 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT
        default:
                break;
        }
+
        return false;
 }
 
@@ -1580,7 +1616,7 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
                break;
 
        case RegionViewNameHighlight:
-               if (is_drawable() && mouse_mode == MouseObject && !internal_editing() && entered_regionview) {
+               if (is_drawable() && mouse_mode == MouseObject && entered_regionview) {
                        set_canvas_cursor_for_region_view (event->crossing.x, entered_regionview);
                        _over_region_trim_target = true;
                }
@@ -1705,8 +1741,8 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
                break;
        case FeatureLineItem:
                {
-                       ArdourCanvas::SimpleLine *line = dynamic_cast<ArdourCanvas::SimpleLine *> (item);
-                       line->property_color_rgba() = 0xFF0000FF;
+                       ArdourCanvas::Line *line = dynamic_cast<ArdourCanvas::Line *> (item);
+                       line->property_fill_color_rgba() = 0xFF0000FF;
                }
                break;
        case SelectionItem:
@@ -1865,8 +1901,8 @@ Editor::leave_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
                break;
        case FeatureLineItem:
                {
-                       ArdourCanvas::SimpleLine *line = dynamic_cast<ArdourCanvas::SimpleLine *> (item);
-                       line->property_color_rgba() = (guint) ARDOUR_UI::config()->canvasvar_ZeroLine.get();;
+                       ArdourCanvas::Line *line = dynamic_cast<ArdourCanvas::Line *> (item);
+                       line->property_fill_color_rgba() = (guint) ARDOUR_UI::config()->canvasvar_ZeroLine.get();;
                }
                break;
 
@@ -1919,7 +1955,7 @@ Editor::scrub (framepos_t frame, double current_x)
                                scrub_reverse_distance = 0;
 
                                delta = 0.01 * (last_scrub_x - current_x);
-                               _session->request_transport_speed (_session->transport_speed() - delta);
+                               _session->request_transport_speed_nonzero (_session->transport_speed() - delta);
                        }
 
                } else {
@@ -1938,7 +1974,7 @@ Editor::scrub (framepos_t frame, double current_x)
                                scrub_reverse_distance = 0;
 
                                delta = 0.01 * (current_x - last_scrub_x);
-                               _session->request_transport_speed (_session->transport_speed() + delta);
+                               _session->request_transport_speed_nonzero (_session->transport_speed() + delta);
                        }
                }
 
@@ -2247,7 +2283,7 @@ Editor::show_verbose_duration_cursor (framepos_t start, framepos_t end, double o
                        ebbt.ticks -= sbbt.ticks;
                } else {
                        ebbt.beats--;
-                       ebbt.ticks = int(Meter::ticks_per_beat) + ebbt.ticks - sbbt.ticks;
+                       ebbt.ticks = int(Timecode::BBT_Time::ticks_per_beat) + ebbt.ticks - sbbt.ticks;
                }
 
                snprintf (buf, sizeof (buf), "%02" PRIu32 "|%02" PRIu32 "|%02" PRIu32, ebbt.bars, ebbt.beats, ebbt.ticks);
@@ -2468,7 +2504,7 @@ Editor::mouse_brush_insert_region (RegionView* rv, framepos_t pos)
        double speed = rtv->track()->speed();
 
        playlist->clear_changes ();
-       boost::shared_ptr<Region> new_region (RegionFactory::create (rv->region()));
+       boost::shared_ptr<Region> new_region (RegionFactory::create (rv->region(), true));
        playlist->add_region (new_region, (framepos_t) (pos * speed));
        _session->add_command (new StatefulDiffCommand (playlist));
 
@@ -2540,7 +2576,7 @@ Editor::add_region_brush_drag (ArdourCanvas::Item* item, GdkEvent* event, Region
        RegionSelection s = get_equivalent_regions (selection->regions, ARDOUR::Properties::edit.property_id);
        _drags->add (new RegionMoveDrag (this, item, region_view, s.by_layer(), true, false));
 
-       begin_reversible_command (_("Drag region brush"));
+       begin_reversible_command (Operations::drag_region_brush);
 }
 
 /** Start a grab where a time range is selected, track(s) are selected, and the
@@ -2581,7 +2617,7 @@ Editor::start_selection_grab (ArdourCanvas::Item* /*item*/, GdkEvent* event)
           creating the new region and another for moving it.
        */
 
-       begin_reversible_command (_("selection grab"));
+       begin_reversible_command (Operations::selection_grab);
 
        boost::shared_ptr<Playlist> playlist = clicked_axisview->playlist();
 
@@ -2627,10 +2663,11 @@ Editor::set_internal_edit (bool yn)
                ARDOUR_UI::instance()->set_tip (mouse_select_button, _("Draw/Edit MIDI Notes"));
                mouse_mode_toggled (mouse_mode);
 
-               /* deselect everything to avoid confusion when e.g. we can't now cut a previously selected
-                  region because cut means "cut note" rather than "cut region".
-               */
-               selection->clear ();
+                pre_internal_mouse_mode = mouse_mode;
+
+                for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
+                        (*i)->enter_internal_edit_mode ();
+                }
 
        } else {
 
@@ -2638,6 +2675,15 @@ Editor::set_internal_edit (bool yn)
                mouse_select_button.get_image ()->show ();
                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) {
+                        /* we were drawing .. flip back to something sensible */
+                        set_mouse_mode (pre_internal_mouse_mode);
+                }
        }
 }