Add load_session to profiling.
[ardour.git] / gtk2_ardour / editor_mouse.cc
index 5ee05336a4a22199f03cc55660a6aeb120763c14..a6446b67c3d7ab35c38271bc3b25fc055cc3460e 100644 (file)
 #include "editor_cursors.h"
 #include "verbose_cursor.h"
 
-#include "ardour/types.h"
-#include "ardour/profile.h"
-#include "ardour/route.h"
-#include "ardour/audio_track.h"
-#include "ardour/playlist.h"
-#include "ardour/audioplaylist.h"
 #include "ardour/audioregion.h"
-#include "ardour/midi_region.h"
-#include "ardour/dB.h"
-#include "ardour/utils.h"
+#include "ardour/operations.h"
+#include "ardour/playlist.h"
+#include "ardour/profile.h"
 #include "ardour/region_factory.h"
-#include "ardour/source_factory.h"
+#include "ardour/route.h"
 #include "ardour/session.h"
-#include "ardour/operations.h"
+#include "ardour/types.h"
 
 #include <bitset>
 
@@ -253,61 +247,38 @@ Editor::set_current_movable (boost::shared_ptr<Movable> m)
 void
 Editor::set_canvas_cursor ()
 {
-       if (_internal_editing) {
+       switch (mouse_mode) {
+       case MouseRange:
+               current_canvas_cursor = _cursors->selector;
+               break;
 
-               switch (mouse_mode) {
-               case MouseDraw:
-                       current_canvas_cursor = _cursors->midi_pencil;
-                       break;
+       case MouseObject:
+               current_canvas_cursor = which_grabber_cursor();
+               break;
 
-               case MouseObject:
-                       current_canvas_cursor = which_grabber_cursor();
-                       break;
+       case MouseDraw:
+               current_canvas_cursor = _cursors->midi_pencil;
+               break;
 
-               case MouseTimeFX:
-                       current_canvas_cursor = _cursors->midi_resize;
-                       break;
+       case MouseGain:
+               current_canvas_cursor = _cursors->cross_hair;
+               break;
 
-               default:
-                       return;
+       case MouseZoom:
+               if (Keyboard::the_keyboard().key_is_down (GDK_Control_L)) {
+                       current_canvas_cursor = _cursors->zoom_out;
+               } else {
+                       current_canvas_cursor = _cursors->zoom_in;
                }
+               break;
 
-       } else {
-
-               switch (mouse_mode) {
-               case MouseRange:
-                       current_canvas_cursor = _cursors->selector;
-                       break;
-
-               case MouseObject:
-                       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;
-
-               case MouseZoom:
-                       if (Keyboard::the_keyboard().key_is_down (GDK_Control_L)) {
-                               current_canvas_cursor = _cursors->zoom_out;
-                       } else {
-                               current_canvas_cursor = _cursors->zoom_in;
-                       }
-                       break;
-
-               case MouseTimeFX:
-                       current_canvas_cursor = _cursors->time_fx; // just use playhead
-                       break;
+       case MouseTimeFX:
+               current_canvas_cursor = _cursors->time_fx; // just use playhead
+               break;
 
-               case MouseAudition:
-                       current_canvas_cursor = _cursors->speaker;
-                       break;
-               }
+       case MouseAudition:
+               current_canvas_cursor = _cursors->speaker;
+               break;
        }
 
        switch (_join_object_range_state) {
@@ -479,6 +450,7 @@ Editor::mouse_mode_toggled (MouseMode m)
        }
 
        set_canvas_cursor ();
+       set_gain_envelope_visibility ();
 
        MouseModeChanged (); /* EMIT SIGNAL */
 }
@@ -589,7 +561,7 @@ Editor::button_selection (ArdourCanvas::Item* /*item*/, GdkEvent* event, ItemTyp
             (mouse_mode != MouseRange) &&
             (mouse_mode != MouseDraw)) ||
            ((event->type != GDK_BUTTON_PRESS && event->type != GDK_BUTTON_RELEASE) || event->button.button > 3) ||
-           internal_editing()) {
+           (internal_editing() && mouse_mode != MouseTimeFX)) {
 
                return;
        }
@@ -640,11 +612,12 @@ Editor::button_selection (ArdourCanvas::Item* /*item*/, GdkEvent* event, ItemTyp
                }
                break;
 
-
        case FadeInHandleItem:
        case FadeInItem:
        case FadeOutHandleItem:
        case FadeOutItem:
+       case StartCrossFadeItem:
+       case EndCrossFadeItem:
                if (doing_object_stuff() || (mouse_mode != MouseRange && mouse_mode != MouseObject)) {
                        set_selected_regionview_from_click (press, op);
                } else if (event->type == GDK_BUTTON_PRESS) {
@@ -655,7 +628,7 @@ Editor::button_selection (ArdourCanvas::Item* /*item*/, GdkEvent* event, ItemTyp
        case ControlPointItem:
                set_selected_track_as_side_effect (op);
                if (doing_object_stuff() || (mouse_mode != MouseRange && mouse_mode != MouseObject)) {
-                       set_selected_control_point_from_click (op, false);
+                       set_selected_control_point_from_click (press, op);
                }
                break;
 
@@ -889,6 +862,7 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
                default:
                        break;
                }
+               break;
 
        case MouseObject:
                switch (item_type) {
@@ -930,6 +904,14 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
                                return true;
                        }
 
+                       case StartCrossFadeItem:
+                               _drags->set (new CrossfadeEdgeDrag (this, reinterpret_cast<AudioRegionView*>(item->get_data("regionview")), item, true), event, 0);
+                               break;
+
+                       case EndCrossFadeItem:
+                               _drags->set (new CrossfadeEdgeDrag (this, reinterpret_cast<AudioRegionView*>(item->get_data("regionview")), item, false), event, 0);
+                               break;
+
                        case FeatureLineItem:
                        {
                                if (Keyboard::modifier_state_contains (event->button.state, Keyboard::TertiaryModifier)) {
@@ -1021,8 +1003,23 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
                                AutomationTimeAxisView* atv = dynamic_cast<AutomationTimeAxisView*> (clicked_axisview);
                                assert (atv);
                                if (parent && dynamic_cast<MidiTimeAxisView*> (parent) && atv->show_regions ()) {
-                                       /* create a MIDI region so that we have somewhere to put automation */
-                                       _drags->set (new RegionCreateDrag (this, item, parent), event);
+
+                                       RouteTimeAxisView* p = dynamic_cast<RouteTimeAxisView*> (parent);
+                                       assert (p);
+                                       boost::shared_ptr<Playlist> pl = p->track()->playlist ();
+                                       if (pl->n_regions() == 0) {
+                                               /* Parent has no regions; create one so that we have somewhere to put automation */
+                                               _drags->set (new RegionCreateDrag (this, item, parent), event);
+                                       } else {
+                                               /* See if there's a region before the click that we can extend, and extend it if so */
+                                               framepos_t const t = event_frame (event);
+                                               boost::shared_ptr<Region> prev = pl->find_next_region (t, End, -1);
+                                               if (!prev) {
+                                                       _drags->set (new RegionCreateDrag (this, item, parent), event);
+                                               } else {
+                                                       prev->set_length (t - prev->position ());
+                                               }
+                                       }
                                } else {
                                        /* rubberband drag to select automation points */
                                        _drags->set (new EditorRubberbandSelectDrag (this, item), event);
@@ -1153,8 +1150,8 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
                        /* drag notes if we're in internal edit mode */
                        _drags->set (new NoteResizeDrag (this, item), event, current_canvas_cursor);
                        return true;
-               } else if ((!internal_editing() || dynamic_cast<AudioRegionView*> (clicked_regionview)) && clicked_regionview) {
-                       /* do time-FX if we're not in internal edit mode, or we are but we clicked on an audio region */
+               } else if (clicked_regionview) {
+                       /* do time-FX  */
                        _drags->set (new TimeFXDrag (this, item, clicked_regionview, selection->regions.by_layer()), event);
                        return true;
                }
@@ -1441,8 +1438,12 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT
                        break;
 
                case NoteItem:
-                       edit_note (item);
+               {
+                       ArdourCanvas::CanvasNoteEvent* e = dynamic_cast<ArdourCanvas::CanvasNoteEvent*> (item);
+                       assert (e);
+                       edit_notes (e->region_view().selection ());
                        break;
+               }
 
                default:
                        break;
@@ -1470,6 +1471,14 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT
                                popup_fade_context_menu (1, event->button.time, item, item_type);
                                break;
 
+                       case StartCrossFadeItem:
+                               popup_xfade_in_context_menu (1, event->button.time, item, item_type);
+                               break;
+
+                       case EndCrossFadeItem:
+                               popup_xfade_out_context_menu (1, event->button.time, item, item_type);
+                               break;
+
                        case StreamItem:
                                popup_track_context_menu (1, event->button.time, item_type, false);
                                break;
@@ -1485,7 +1494,7 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT
                        case SelectionItem:
                                popup_track_context_menu (1, event->button.time, item_type, true);
                                break;
-
+                               
                        case AutomationTrackItem:
                                popup_track_context_menu (1, event->button.time, item_type, false);
                                break;
@@ -2302,12 +2311,13 @@ Editor::edit_control_point (ArdourCanvas::Item* item)
 }
 
 void
-Editor::edit_note (ArdourCanvas::Item* item)
+Editor::edit_notes (MidiRegionView::Selection const & s)
 {
-       ArdourCanvas::CanvasNoteEvent* e = dynamic_cast<ArdourCanvas::CanvasNoteEvent*> (item);
-       assert (e);
-
-       EditNoteDialog d (&e->region_view(), e);
+       if (s.empty ()) {
+               return;
+       }
+       
+       EditNoteDialog d (&(*s.begin())->region_view(), s);
        d.set_position (Gtk::WIN_POS_MOUSE);
        ensure_float (d);
 
@@ -2412,10 +2422,6 @@ Editor::point_trim (GdkEvent* event, framepos_t new_bound)
                        for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin();
                             i != selection->regions.by_layer().end(); ++i)
                        {
-                               if ( (*i) == NULL){
-                                   cerr << "region view contains null region" << endl;
-                               }
-
                                if (!(*i)->region()->locked()) {
                                        (*i)->region()->clear_changes ();
                                        (*i)->region()->trim_front (new_bound);