Delta Cursor option backported from trunk
[ardour.git] / gtk2_ardour / editor_mouse.cc
index c46571ada6ed1c4e957826f37716088a6bc5df6b..06b8c6fa3f1181d680afc4cc716dccaf29b02ed8 100644 (file)
@@ -1130,7 +1130,7 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
                if (mouse_mode == MouseGain) {
                        ArdourCanvas::Line *line = dynamic_cast<ArdourCanvas::Line *> (item);
                        if (line)
-                               line->property_fill_color_rgba() = color_map[cEnteredGainLine];
+                               line->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_EnteredGainLine.get();
                        if (is_drawable()) {
                                track_canvas.get_window()->set_cursor (*fader_cursor);
                        }
@@ -1144,7 +1144,7 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
                        {
                                ArdourCanvas::Line *line = dynamic_cast<ArdourCanvas::Line *> (item);
                                if (line)
-                                       line->property_fill_color_rgba() = color_map[cEnteredAutomationLine];
+                                       line->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_EnteredAutomationLine.get();
                        }
                        if (is_drawable()) {
                                track_canvas.get_window()->set_cursor (*fader_cursor);
@@ -1230,7 +1230,7 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
                if ((marker = static_cast<Marker *> (item->get_data ("marker"))) == 0) {
                        break;
                }
-               marker->set_color_rgba (color_map[cEnteredMarker]);
+               marker->set_color_rgba (ARDOUR_UI::config()->canvasvar_EnteredMarker.get());
                // fall through
        case MeterMarkerItem:
        case TempoMarkerItem:
@@ -1449,9 +1449,9 @@ Editor::motion_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item
                */
                if (!drag_info.move_threshold_passed) {
 
-                       bool x_threshold_passed =  (abs ((int) (drag_info.current_pointer_x - drag_info.grab_x)) > 4);
-                       bool y_threshold_passed =  (abs ((int) (drag_info.current_pointer_y - drag_info.grab_y)) > 4);
-
+                       bool x_threshold_passed =  (abs ((nframes64_t) (drag_info.current_pointer_x - drag_info.grab_x)) > 4LL);
+                       bool y_threshold_passed =  (abs ((nframes64_t) (drag_info.current_pointer_y - drag_info.grab_y)) > 4LL);
+                       
                        drag_info.move_threshold_passed = (x_threshold_passed || y_threshold_passed);
                        
                        // and change the initial grab loc/frame if this drag info wants us to
@@ -1563,7 +1563,7 @@ Editor::start_grab (GdkEvent* event, Gdk::Cursor *cursor)
                drag_info.y_constrained = false;
        }
 
-       drag_info.grab_frame = event_frame(event, &drag_info.grab_x, &drag_info.grab_y);
+       drag_info.grab_frame = event_frame (event, &drag_info.grab_x, &drag_info.grab_y);
        drag_info.last_pointer_frame = drag_info.grab_frame;
        drag_info.current_pointer_frame = drag_info.grab_frame;
        drag_info.current_pointer_x = drag_info.grab_x;
@@ -1620,7 +1620,6 @@ Editor::end_grab (ArdourCanvas::Item* item, GdkEvent* event)
        stop_canvas_autoscroll ();
 
        if (drag_info.item == 0) {
-               cerr << "end grab with no item\n";
                return false;
        }
        
@@ -1708,7 +1707,7 @@ Editor::fade_in_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
        nframes_t pos;
        nframes_t fade_length;
 
-       if ((int32_t)drag_info.current_pointer_frame > drag_info.pointer_frame_offset) {
+       if (drag_info.current_pointer_frame > drag_info.pointer_frame_offset) {
                pos = drag_info.current_pointer_frame - drag_info.pointer_frame_offset;
        }
        else {
@@ -1753,7 +1752,7 @@ Editor::fade_in_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* even
 
        if (drag_info.first_move) return;
 
-       if ((int32_t)drag_info.current_pointer_frame > drag_info.pointer_frame_offset) {
+       if (drag_info.current_pointer_frame > drag_info.pointer_frame_offset) {
                pos = drag_info.current_pointer_frame - drag_info.pointer_frame_offset;
        } else {
                pos = 0;
@@ -1815,10 +1814,9 @@ Editor::fade_out_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event
        nframes_t pos;
        nframes_t fade_length;
 
-       if ((long)drag_info.current_pointer_frame > drag_info.pointer_frame_offset) {
+       if (drag_info.current_pointer_frame > drag_info.pointer_frame_offset) {
                pos = drag_info.current_pointer_frame - drag_info.pointer_frame_offset;
-       }
-       else {
+       } else {
                pos = 0;
        }
 
@@ -1863,7 +1861,7 @@ Editor::fade_out_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* eve
        nframes_t pos;
        nframes_t fade_length;
 
-       if ((long)drag_info.current_pointer_frame > drag_info.pointer_frame_offset) {
+       if (drag_info.current_pointer_frame > drag_info.pointer_frame_offset) {
                pos = drag_info.current_pointer_frame - drag_info.pointer_frame_offset;
        }
        else {
@@ -1945,7 +1943,7 @@ Editor::cursor_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
        Cursor* cursor = (Cursor *) drag_info.data;
        nframes_t adjusted_frame;
        
-       if ((long)drag_info.current_pointer_frame > drag_info.pointer_frame_offset) {
+       if (drag_info.current_pointer_frame > drag_info.pointer_frame_offset) {
                adjusted_frame = drag_info.current_pointer_frame - drag_info.pointer_frame_offset;
        }
        else {
@@ -2061,10 +2059,9 @@ Editor::marker_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
 
 
        nframes_t newframe;
-       if (drag_info.pointer_frame_offset <= (long) drag_info.current_pointer_frame) {
+       if (drag_info.pointer_frame_offset <= drag_info.current_pointer_frame) {
                newframe = drag_info.current_pointer_frame - drag_info.pointer_frame_offset;
-       }
-       else {
+       } else {
                newframe = 0;
        }
 
@@ -2220,7 +2217,7 @@ Editor::start_meter_marker_copy_grab (ArdourCanvas::Item* item, GdkEvent* event)
        // The actual copying is not done before we reach the finish callback.
        char name[64];
        snprintf (name, sizeof(name), "%g/%g", meter_marker->meter().beats_per_bar(), meter_marker->meter().note_divisor ());
-       MeterMarker* new_marker = new MeterMarker(*this, *meter_group, color_map[cMeterMarker], name, 
+       MeterMarker* new_marker = new MeterMarker(*this, *meter_group, ARDOUR_UI::config()->canvasvar_MeterMarker.get(), name, 
                                                  *new MeterSection(meter_marker->meter()));
 
        drag_info.item = &new_marker->the_item();
@@ -2242,7 +2239,7 @@ Editor::meter_marker_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* e
        MeterMarker* marker = (MeterMarker *) drag_info.data;
        nframes_t adjusted_frame;
 
-       if ((long)drag_info.current_pointer_frame > drag_info.pointer_frame_offset) {
+       if (drag_info.current_pointer_frame > drag_info.pointer_frame_offset) {
                adjusted_frame = drag_info.current_pointer_frame - drag_info.pointer_frame_offset;
        }
        else {
@@ -2351,7 +2348,7 @@ Editor::start_tempo_marker_copy_grab (ArdourCanvas::Item* item, GdkEvent* event)
        // The actual copying is not done before we reach the finish callback.
        char name[64];
        snprintf (name, sizeof (name), "%.2f", tempo_marker->tempo().beats_per_minute());
-       TempoMarker* new_marker = new TempoMarker(*this, *tempo_group, color_map[cTempoMarker], name, 
+       TempoMarker* new_marker = new TempoMarker(*this, *tempo_group, ARDOUR_UI::config()->canvasvar_TempoMarker.get(), name, 
                                                  *new TempoSection(tempo_marker->tempo()));
 
        drag_info.item = &new_marker->the_item();
@@ -2373,7 +2370,7 @@ Editor::tempo_marker_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* e
        TempoMarker* marker = (TempoMarker *) drag_info.data;
        nframes_t adjusted_frame;
        
-       if ((long)drag_info.current_pointer_frame > drag_info.pointer_frame_offset) {
+       if (drag_info.current_pointer_frame > drag_info.pointer_frame_offset) {
                adjusted_frame = drag_info.current_pointer_frame - drag_info.pointer_frame_offset;
        }
        else {
@@ -2768,7 +2765,7 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
                drag_info.want_move_threshold = false; // don't copy again
 
                /* duplicate the region(s) */
-               
+
                vector<RegionView*> new_regionviews;
                
                for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i) {
@@ -2801,7 +2798,7 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
                /* reset drag_info data to reflect the fact that we are dragging the copies */
                
                drag_info.data = new_regionviews.front();
-               
+
                swap_grab (new_regionviews.front()->get_canvas_group (), 0, event->motion.time);
        }
 
@@ -2989,14 +2986,14 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
 
        if (drag_info.move_threshold_passed) {
 
-               if ((int32_t)drag_info.current_pointer_frame > drag_info.pointer_frame_offset) {
+               if (drag_info.current_pointer_frame > drag_info.pointer_frame_offset) {
 
                        nframes_t sync_frame;
                        nframes_t sync_offset;
                        int32_t sync_dir;
            
                        pending_region_position = drag_info.current_pointer_frame - drag_info.pointer_frame_offset;
-           
+
                        sync_offset = rv->region()->sync_offset (sync_dir);
                        sync_frame = rv->region()->adjust_to_sync (pending_region_position);
 
@@ -3028,13 +3025,13 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
                        /* now compute the canvas unit distance we need to move the regiondrag_info.last_trackview->order
                           to make it appear at the new location.
                        */
-           
+
                        if (pending_region_position > drag_info.last_frame_position) {
                                x_delta = ((double) (pending_region_position - drag_info.last_frame_position) / frames_per_unit);
                        } else {
                                x_delta = -((double) (drag_info.last_frame_position - pending_region_position) / frames_per_unit);
                        }
-           
+
                        drag_info.last_frame_position = pending_region_position;
            
                } else {
@@ -3058,6 +3055,7 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
                return;
        } 
 
+
        if (x_delta < 0) {
                for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i) {
 
@@ -3180,10 +3178,11 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
                                if (-x_delta > ix1) {
                                        x_delta = -ix1;
                                }
-                       } else if ((x_delta > 0) &&(rv->region()->last_frame() > max_frames - x_delta)) {
+                       } else if ((x_delta > 0) && (rv->region()->last_frame() > max_frames - x_delta)) {
                                x_delta = max_frames - rv->region()->last_frame();
                        }
 
+
                        if (drag_info.first_move) {
 
                                /* hide any dependent views */
@@ -3199,7 +3198,6 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
                                rv->get_canvas_group()->raise_to_top();
                                rv->get_time_axis_view().canvas_display->raise_to_top();
                                cursor_group->raise_to_top();
-
                                rv->fake_set_opaque (true);
                        }
                        
@@ -3234,6 +3232,7 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
        RouteTimeAxisView* atv;
        bool regionview_y_movement;
        bool regionview_x_movement;
+       vector<RegionView*> copies;
 
        /* first_move is set to false if the regionview has been moved in the 
           motion handler. 
@@ -3254,6 +3253,13 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
 
        if (drag_info.brushing) {
                /* all changes were made during motion event handlers */
+               
+               if (drag_info.copy) {
+                       for (list<RegionView*>::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
+                               copies.push_back (*i);
+                       }
+               }
+
                goto out;
        }
 
@@ -3296,7 +3302,7 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
                vector<RegionView*> new_selection;
 
                for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ) {
-           
+                       
                        RegionView* rv = (*i);              
 
                        double ix1, ix2, iy1, iy2;
@@ -3308,7 +3314,7 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
 
                        boost::shared_ptr<Playlist> from_playlist = rv->region()->playlist();
                        boost::shared_ptr<Playlist> to_playlist = atv2->playlist();
-           
+
                        where = (nframes_t) (unit_to_frame (ix1) * speed);
                        boost::shared_ptr<Region> new_region (RegionFactory::create (rv->region()));
 
@@ -3332,6 +3338,12 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
                                session->add_command (new MementoCommand<Playlist>(*from_playlist, &from_playlist->get_state(), 0));    
                                from_playlist->remove_region ((rv->region()));
                                session->add_command (new MementoCommand<Playlist>(*from_playlist, 0, &from_playlist->get_state()));    
+
+                       } else {
+
+                               /* the regionview we dragged around is a temporary copy, queue it for deletion */
+                               
+                               copies.push_back (rv);
                        }
 
                        latest_regionview = 0;
@@ -3346,11 +3358,6 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
                                new_selection.push_back (latest_regionview);
                        }
 
-                       if (drag_info.copy) {
-                               // get rid of the copy
-                               delete rv;
-                       } 
-
                        /* OK, this is where it gets tricky. If the playlist was being used by >1 tracks, and the region
                           was selected in all of them, then removing it from the playlist will have removed all
                           trace of it from the selection (i.e. there were N regions selected, we removed 1,
@@ -3363,12 +3370,19 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
                           here. if the region selection is not empty, then restart the loop because we know that
                           we must have removed at least the region(view) we've just been working on as well as any
                           that we processed on previous iterations.
+
+                          EXCEPT .... if we are doing a copy drag, then the selection hasn't been modified and
+                          we can just iterate.
                        */
 
-                       if (selection->regions.empty()) {
-                               break;
-                       } else { 
-                               i = selection->regions.by_layer().begin();
+                       if (drag_info.copy) {
+                               ++i;
+                       } else {
+                               if (selection->regions.empty()) {
+                                       break;
+                               } else { 
+                                       i = selection->regions.by_layer().begin();
+                               }
                        }
                } 
 
@@ -3435,7 +3449,7 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
                                }
 
                                /* add it */
-                               
+
                                latest_regionview = 0;
                                sigc::connection c = atv->view()->RegionViewAdded.connect (mem_fun(*this, &Editor::collect_new_region_view));
                                to_playlist->add_region (newregion, (nframes_t) (where * atv->get_diskstream()->speed()));
@@ -3462,10 +3476,8 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
 
                        session->add_command (new MementoCommand<Playlist>(*to_playlist, 0, &to_playlist->get_state()));
 
-                       /* get rid of the copy */
-
                        if (drag_info.copy) {
-                               delete rv;
+                               copies.push_back (rv);
                        }
                }
        }
@@ -3475,6 +3487,10 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
        if (!nocommit) {
                commit_reversible_command ();
        }
+
+       for (vector<RegionView*>::iterator x = copies.begin(); x != copies.end(); ++x) {
+               delete *x;
+       }
 }
 
 void
@@ -3785,10 +3801,9 @@ Editor::drag_selection (ArdourCanvas::Item* item, GdkEvent* event)
        nframes_t length;
        nframes_t pending_position;
 
-       if ((int32_t) drag_info.current_pointer_frame > drag_info.pointer_frame_offset) {
+       if (drag_info.current_pointer_frame > drag_info.pointer_frame_offset) {
                pending_position = drag_info.current_pointer_frame - drag_info.pointer_frame_offset;
-       }
-       else {
+       } else {
                pending_position = 0;
        }
        
@@ -4034,7 +4049,7 @@ Editor::trim_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
                begin_reversible_command (trim_type);
 
                for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i) {
-                       (*i)->fake_set_opaque(false);
+                       (*i)->fake_set_opaque(false);                   
                        (*i)->region()->freeze ();
                
                        AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i);