missing template dir patch from tim, fix extend selection to track when track is...
[ardour.git] / gtk2_ardour / editor_canvas.cc
index 73aeef79b296f1ff6b0ab410f28f3e9f90e0d637..4a1fc10b9c1926a2b8a5363f68257be871e78e44 100644 (file)
 using namespace std;
 using namespace sigc;
 using namespace ARDOUR;
+using namespace PBD;
 using namespace Gtk;
 using namespace Glib;
 using namespace Gtkmm2ext;
 using namespace Editing;
 
-/* XXX this is a hack. it ought to be the maximum value of an jack_nframes_t */
+/* XXX this is a hack. it ought to be the maximum value of an nframes_t */
 
 const double max_canvas_coordinate = (double) JACK_MAX_FRAMES;
 
@@ -91,6 +92,7 @@ Editor::initialize_canvas ()
        /* don't try to center the canvas */
 
        track_canvas.set_center_scroll_region (false);
+       track_canvas.set_dither         (Gdk::RGB_DITHER_NONE);
 
        track_canvas.signal_event().connect (bind (mem_fun (*this, &Editor::track_canvas_event), (ArdourCanvas::Item*) 0));
        track_canvas.set_name ("EditorMainCanvas");
@@ -127,11 +129,12 @@ Editor::initialize_canvas ()
        
        time_line_group = new ArdourCanvas::Group (*track_canvas.root(), 0.0, 0.0);
        cursor_group = new ArdourCanvas::Group (*track_canvas.root(), 0.0, 0.0);
-       
+
        time_canvas.set_name ("EditorTimeCanvas");
        time_canvas.add_events (Gdk::POINTER_MOTION_HINT_MASK);
        time_canvas.set_flags (CAN_FOCUS);
        time_canvas.set_center_scroll_region (false);
+       time_canvas.set_dither          (Gdk::RGB_DITHER_NONE);
        
        meter_group = new ArdourCanvas::Group (*time_canvas.root(), 0.0, 0.0);
        tempo_group = new ArdourCanvas::Group (*time_canvas.root(), 0.0, timebar_height);
@@ -263,19 +266,63 @@ Editor::initialize_canvas ()
        
        edit_cursor = new Cursor (*this, "blue", &Editor::canvas_edit_cursor_event);
        playhead_cursor = new Cursor (*this, "red", &Editor::canvas_playhead_cursor_event);
-       
+
+       initial_ruler_update_required = true;
        track_canvas.signal_size_allocate().connect (mem_fun(*this, &Editor::track_canvas_allocate));
+
 }
 
 void
 Editor::track_canvas_allocate (Gtk::Allocation alloc)
 {
-       static bool first_time = true;
+       canvas_allocation = alloc;
+
+       if (!initial_ruler_update_required) {
+               if (!canvas_idle_queued) {
+                       /* call this first so that we do stuff before any pending redraw */
+                       Glib::signal_idle().connect (mem_fun (*this, &Editor::track_canvas_idle), false);
+                       canvas_idle_queued = true;
+               }
+               return;
+       } 
+
+       initial_ruler_update_required = false;
+       
+       track_canvas_idle ();
+}
+
+bool
+Editor::track_canvas_idle ()
+{
+       if (canvas_idle_queued) {
+               canvas_idle_queued = false;
+       }
+
+       canvas_width = canvas_allocation.get_width();
+       canvas_height = canvas_allocation.get_height();
+
+       full_canvas_height = canvas_height;
 
-       canvas_width = alloc.get_width();
-       canvas_height = alloc.get_height();
+       if (session) {
+               TrackViewList::iterator i;
+               double height = 0;
+
+               for (i = track_views.begin(); i != track_views.end(); ++i) {
+                       if ((*i)->control_parent) {
+                               height += (*i)->effective_height;
+                               height += track_spacing;
+                       }
+               }
+               
+               if (height) {
+                       height -= track_spacing;
+               }
+
+               full_canvas_height = height;
+       }
 
-       zoom_range_clock.set ((jack_nframes_t) floor ((canvas_width * frames_per_unit)));
+
+       zoom_range_clock.set ((nframes_t) floor ((canvas_width * frames_per_unit)));
        edit_cursor->set_position (edit_cursor->current_frame);
        playhead_cursor->set_position (playhead_cursor->current_frame);
 
@@ -315,16 +362,12 @@ Editor::track_canvas_allocate (Gtk::Allocation alloc)
                transport_punchout_line->property_y2() = canvas_height;
        }
                
-       update_fixed_rulers ();
-
-       if (is_visible() && first_time) {
-               tempo_map_changed (Change (0));
-               first_time = false;
-       } else {
-               redisplay_tempo ();
-       }
+       update_fixed_rulers();
+       tempo_map_changed (Change (0));
        
        Resized (); /* EMIT_SIGNAL */
+
+       return false;
 }
 
 void
@@ -411,6 +454,8 @@ Editor::track_canvas_drag_data_received (const RefPtr<Gdk::DragContext>& context
                                         const SelectionData& data,
                                         guint info, guint time)
 {
+       cerr << "dropping, target = " << data.get_target() << endl;
+
        if (data.get_target() == "regions") {
                drop_regions (context, x, y, data, info, time);
        } else {
@@ -430,7 +475,7 @@ Editor::drop_paths (const RefPtr<Gdk::DragContext>& context,
        vector<ustring> paths;
        string spath;
        GdkEvent ev;
-       jack_nframes_t frame;
+       nframes_t frame;
 
        if (convert_drop_to_paths (paths, context, x, y, data, info, time)) {
                goto out;
@@ -458,7 +503,7 @@ Editor::drop_paths (const RefPtr<Gdk::DragContext>& context,
 
                /* drop onto canvas background: create new tracks */
 
-               jack_nframes_t pos = 0;
+               nframes_t pos = 0;
                do_embed (paths, false, ImportAsTrack, 0, pos, false);
                
        } else if ((tv = dynamic_cast<AudioTimeAxisView*>(tvp)) != 0) {
@@ -480,15 +525,16 @@ Editor::drop_regions (const RefPtr<Gdk::DragContext>& context,
                      const SelectionData& data,
                      guint info, guint time)
 {
-       const DnDTreeView::SerializedObjectPointers* sr = reinterpret_cast<const DnDTreeView::SerializedObjectPointers*> (data.get_data());
+       const SerializedObjectPointers<boost::shared_ptr<Region> >* sr = 
+               reinterpret_cast<const SerializedObjectPointers<boost::shared_ptr<Region> > *> (data.get_data());
 
        for (uint32_t i = 0; i < sr->cnt; ++i) {
 
-               Region* r = reinterpret_cast<Region*> (sr->ptr[i]);
-               AudioRegion* ar;
+               boost::shared_ptr<Region> r = sr->data[i];
+               boost::shared_ptr<AudioRegion> ar;
 
-               if ((ar = dynamic_cast<AudioRegion*>(r)) != 0) {
-                       insert_region_list_drag (*ar, x, y);
+               if ((ar = boost::dynamic_pointer_cast<AudioRegion>(r)) != 0) {
+                       insert_region_list_drag (ar, x, y);
                }
        }
 
@@ -498,8 +544,8 @@ Editor::drop_regions (const RefPtr<Gdk::DragContext>& context,
 void
 Editor::maybe_autoscroll (GdkEvent* event)
 {
-       jack_nframes_t rightmost_frame = leftmost_frame + current_page_frames();
-       jack_nframes_t frame = drag_info.current_pointer_frame;
+       nframes_t rightmost_frame = leftmost_frame + current_page_frames();
+       nframes_t frame = drag_info.current_pointer_frame;
        bool startit = false;
 
        static int last_autoscroll_direction = 0;
@@ -528,7 +574,7 @@ Editor::maybe_autoscroll (GdkEvent* event)
        }
 
 
-       if (autoscroll_direction != last_autoscroll_direction) {
+       if ((autoscroll_direction != last_autoscroll_direction) || (leftmost_frame < frame < rightmost_frame)) {
                stop_canvas_autoscroll ();
        }
        
@@ -537,23 +583,21 @@ Editor::maybe_autoscroll (GdkEvent* event)
        }
 
        last_autoscroll_direction = autoscroll_direction;
-       drag_info.last_pointer_frame = drag_info.current_pointer_frame;
 }
 
 gint
 Editor::_autoscroll_canvas (void *arg)
 {
-       return ((Editor *) arg)->autoscroll_canvas ();
+        return ((Editor *) arg)->autoscroll_canvas ();
 }
 
-gint
+bool
 Editor::autoscroll_canvas ()
 {
-       jack_nframes_t new_frame;
-       bool keep_calling = true;
-       jack_nframes_t limit = max_frames - current_page_frames();
+       nframes_t new_frame;
+       nframes_t limit = max_frames - current_page_frames();
        GdkEventMotion ev;
-       jack_nframes_t target_frame;
+       nframes_t target_frame;
 
        if (autoscroll_direction < 0) {
                if (leftmost_frame < autoscroll_distance) {
@@ -571,10 +615,6 @@ Editor::autoscroll_canvas ()
                target_frame = drag_info.current_pointer_frame + autoscroll_distance;
        }
 
-       if (new_frame != leftmost_frame) {
-               reposition_x_origin (new_frame);
-       }
-
        /* now fake a motion event to get the object that is being dragged to move too */
 
        ev.type = GDK_MOTION_NOTIFY;
@@ -594,45 +634,52 @@ Editor::autoscroll_canvas ()
 
                /* connect the timeout so that we get called repeatedly */
 
-               autoscroll_timeout_tag = gtk_timeout_add (20, _autoscroll_canvas, this);
-               keep_calling = false;
+               autoscroll_timeout_tag = g_idle_add ( _autoscroll_canvas, this);
+               return false;
+
+       } 
 
-       } else if (autoscroll_cnt == 50) { /* 0.5 seconds */
+       if (new_frame != leftmost_frame) {
+               reposition_x_origin (new_frame);
+       }
+
+       if (autoscroll_cnt == 50) { /* 0.5 seconds */
                
                /* after about a while, speed up a bit by changing the timeout interval */
 
-               autoscroll_distance = (jack_nframes_t) floor (current_page_frames()/50.0f);
+               autoscroll_distance = (nframes_t) floor (current_page_frames()/30.0f);
                
-       } else if (autoscroll_cnt == 75) { /* 1.0 seconds */
+       } else if (autoscroll_cnt == 150) { /* 1.0 seconds */
 
-               autoscroll_distance = (jack_nframes_t) floor (current_page_frames()/20.0f);
+               autoscroll_distance = (nframes_t) floor (current_page_frames()/20.0f);
 
-       } else if (autoscroll_cnt == 100) { /* 1.5 seconds */
+       } else if (autoscroll_cnt == 300) { /* 1.5 seconds */
 
                /* after about another while, speed up by increasing the shift per callback */
 
-               autoscroll_distance =  (jack_nframes_t) floor (current_page_frames()/10.0f);
+               autoscroll_distance =  (nframes_t) floor (current_page_frames()/10.0f);
 
        } 
 
-       return keep_calling;
+       return true;
 }
 
 void
 Editor::start_canvas_autoscroll (int dir)
 {
-       if (!session) {
+       if (!session || autoscroll_active) {
                return;
        }
 
        stop_canvas_autoscroll ();
 
+       autoscroll_active = true;
        autoscroll_direction = dir;
-       autoscroll_distance = (jack_nframes_t) floor (current_page_frames()/100.0);
+       autoscroll_distance = (nframes_t) floor (current_page_frames()/50.0);
        autoscroll_cnt = 0;
        
        /* do it right now, which will start the repeated callbacks */
-       
+
        autoscroll_canvas ();
 }
 
@@ -640,9 +687,11 @@ void
 Editor::stop_canvas_autoscroll ()
 {
        if (autoscroll_timeout_tag >= 0) {
-               gtk_timeout_remove (autoscroll_timeout_tag);
+               g_source_remove (autoscroll_timeout_tag);
                autoscroll_timeout_tag = -1;
        }
+
+       autoscroll_active = false;
 }
 
 gint