use a different approach for indicating expose rects (from robin gareus). #ifdef...
[ardour.git] / gtk2_ardour / editor_canvas.cc
index 68c7662ec43b637546c569c5867a9ad9f5367211..8ad2abdfad3ca77f82c10887b189d96d4fb28472 100644 (file)
@@ -236,7 +236,7 @@ Editor::initialize_canvas ()
           handlers.
        */
 
-       _track_canvas->signal_scroll_event().connect (sigc::mem_fun (*this, &Editor::track_canvas_scroll_event));
+       _track_canvas->signal_scroll_event().connect (sigc::bind (sigc::mem_fun (*this, &Editor::canvas_scroll_event), true));
        _track_canvas->signal_motion_notify_event().connect (sigc::mem_fun (*this, &Editor::track_canvas_motion_notify_event));
        _track_canvas->signal_button_press_event().connect (sigc::mem_fun (*this, &Editor::track_canvas_button_press_event));
        _track_canvas->signal_button_release_event().connect (sigc::mem_fun (*this, &Editor::track_canvas_button_release_event));
@@ -266,6 +266,8 @@ Editor::initialize_canvas ()
 
        _track_canvas_viewport->signal_size_allocate().connect (sigc::mem_fun(*this, &Editor::track_canvas_viewport_allocate));
 
+       initialize_rulers ();
+
        ColorsChanged.connect (sigc::mem_fun (*this, &Editor::color_handler));
        color_handler();
 
@@ -491,18 +493,46 @@ Editor::drop_paths (const RefPtr<Gdk::DragContext>& context,
 void
 Editor::maybe_autoscroll (bool allow_horiz, bool allow_vert, bool from_headers)
 {
-       if (!Config->get_autoscroll_editor ()) {
+       if (!Config->get_autoscroll_editor () || autoscroll_active ()) {
                return;
        }
 
+       /* define a rectangular boundary for scrolling. If the mouse moves
+        * outside of this area and/or continue to be outside of this area,
+        * then we will continuously auto-scroll the canvas in the appropriate
+        * direction(s)
+        *
+        * the boundary is defined in coordinates relative to the toplevel
+        * window since that is what we're going to call ::get_pointer() on
+        * during autoscrolling to determine if we're still outside the
+        * boundary or not.
+        */
+
        ArdourCanvas::Rect scrolling_boundary;
        Gtk::Allocation alloc;
-       
+       int cx, cy;
+
        if (from_headers) {
                alloc = controls_layout.get_allocation ();
-       } else {
+       } else {        
                alloc = _track_canvas_viewport->get_allocation ();
+               cx = alloc.get_x();
+               cy = alloc.get_y();
+
+               /* reduce height by the height of the timebars, which happens
+                  to correspond to the position of the hv_scroll_group.
+               */
                
+               alloc.set_height (alloc.get_height() - hv_scroll_group->position().y);
+               alloc.set_y (alloc.get_y() + hv_scroll_group->position().y);
+
+               /* now reduce it again so that we start autoscrolling before we
+                * move off the top or bottom of the canvas
+                */
+
+               alloc.set_height (alloc.get_height() - 20);
+               alloc.set_y (alloc.get_y() + 10);
+
                /* the effective width of the autoscroll boundary so
                   that we start scrolling before we hit the edge.
                   
@@ -515,19 +545,18 @@ Editor::maybe_autoscroll (bool allow_horiz, bool allow_vert, bool from_headers)
                        alloc.set_width (alloc.get_width() - 20);
                        alloc.set_x (alloc.get_x() + 10);
                } 
+
        }
        
-       scrolling_boundary = ArdourCanvas::Rect (alloc.get_x(), alloc.get_y(), 
-                                                alloc.get_x() + alloc.get_width(), 
-                                                alloc.get_y() + alloc.get_height());
+       scrolling_boundary = ArdourCanvas::Rect (alloc.get_x(), alloc.get_y(), alloc.get_x() + alloc.get_width(), alloc.get_y() + alloc.get_height());
        
        int x, y;
        Gdk::ModifierType mask;
 
        get_window()->get_pointer (x, y, mask);
 
-       if ((allow_horiz && (x < scrolling_boundary.x0 || x >= scrolling_boundary.x1)) ||
-           (allow_vert && (y < scrolling_boundary.y0 || y >= scrolling_boundary.y1))) {
+       if ((allow_horiz && ((x < scrolling_boundary.x0 && leftmost_frame > 0) || x >= scrolling_boundary.x1)) ||
+           (allow_vert && ((y < scrolling_boundary.y0 && vertical_adjustment.get_value() > 0)|| y >= scrolling_boundary.y1))) {
                start_canvas_autoscroll (allow_horiz, allow_vert, scrolling_boundary);
        }
 }
@@ -550,6 +579,7 @@ Editor::autoscroll_canvas ()
        get_window()->get_pointer (x, y, mask);
 
        VisualChange vc;
+       bool vertical_motion = false;
 
        if (autoscroll_horizontal_allowed) {
 
@@ -597,8 +627,8 @@ Editor::autoscroll_canvas ()
 
        if (autoscroll_vertical_allowed) {
                
-               const double vertical_pos = vertical_adjustment.get_value();
-               const int speed_factor = 20;
+               // const double vertical_pos = vertical_adjustment.get_value();
+               const int speed_factor = 10;
 
                /* vertical */ 
                
@@ -608,20 +638,21 @@ Editor::autoscroll_canvas ()
 
                        if (autoscroll_cnt && (autoscroll_cnt % speed_factor == 0)) {
                                y_motion = scroll_up_one_track ();
+                               vertical_motion = true;
                        }
 
                } else if (y > autoscroll_boundary.y1) {
 
                        if (autoscroll_cnt && (autoscroll_cnt % speed_factor == 0)) {
                                y_motion = scroll_down_one_track ();
-                               
+                               vertical_motion = true;
                        }
                }
 
                no_stop = true;
        }
 
-       if (vc.pending) {
+       if (vc.pending || vertical_motion) {
 
                /* change horizontal first */
 
@@ -640,26 +671,33 @@ Editor::autoscroll_canvas ()
                
                /* the motion handler expects events in canvas coordinate space */
 
-               /* first convert from Editor window coordinates to canvas
-                * window coordinates
+               /* we asked for the mouse position above (::get_pointer()) via
+                * our own top level window (we being the Editor). Convert into 
+                * coordinates within the canvas window.
                 */
 
                int cx;
                int cy;
 
-               /* clamp x and y to remain within the visible area */
+               translate_coordinates (*_track_canvas, x, y, cx, cy);
 
-               x = min (max ((ArdourCanvas::Coord) x, autoscroll_boundary.x0), autoscroll_boundary.x1);
-               y = min (max ((ArdourCanvas::Coord) y, autoscroll_boundary.y0), autoscroll_boundary.y1);
+               /* clamp x and y to remain within the autoscroll boundary,
+                * which is defined in window coordinates
+                */
 
-               translate_coordinates (*_track_canvas_viewport, x, y, cx, cy);
+               x = min (max ((ArdourCanvas::Coord) cx, autoscroll_boundary.x0), autoscroll_boundary.x1);
+               y = min (max ((ArdourCanvas::Coord) cy, autoscroll_boundary.y0), autoscroll_boundary.y1);
+
+               /* now convert from Editor window coordinates to canvas
+                * window coordinates
+                */
 
                ArdourCanvas::Duple d = _track_canvas->window_to_canvas (ArdourCanvas::Duple (cx, cy));
                ev.x = d.x;
                ev.y = d.y;
 
                motion_handler (0, (GdkEvent*) &ev, true);
-
+               
        } else if (no_stop) {
 
                /* not changing visual state but pointer is outside the scrolling boundary
@@ -699,7 +737,7 @@ Editor::autoscroll_canvas ()
                ev.y = d.y;
 
                motion_handler (0, (GdkEvent*) &ev, true);
-
+               
        } else {
                stop_canvas_autoscroll ();
                return false;
@@ -811,6 +849,17 @@ Editor::set_horizontal_position (double p)
 void
 Editor::color_handler()
 {
+       ArdourCanvas::Color base = ARDOUR_UI::config()->get_canvasvar_RulerBase();
+       ArdourCanvas::Color text = ARDOUR_UI::config()->get_canvasvar_RulerText();
+       timecode_ruler->set_fill_color (base);
+       timecode_ruler->set_outline_color (text);
+       minsec_ruler->set_fill_color (base);
+       minsec_ruler->set_outline_color (text);
+       samples_ruler->set_fill_color (base);
+       samples_ruler->set_outline_color (text);
+       bbt_ruler->set_fill_color (base);
+       bbt_ruler->set_outline_color (text);
+       
        playhead_cursor->set_color (ARDOUR_UI::config()->get_canvasvar_PlayHead());
        _verbose_cursor->set_color (ARDOUR_UI::config()->get_canvasvar_VerboseCanvasCursor());
 
@@ -891,6 +940,25 @@ Editor::set_canvas_cursor (Gdk::Cursor* cursor, bool save)
        }
 }
 
+void
+Editor::push_canvas_cursor (Gdk::Cursor* cursor)
+{
+       if (cursor) {
+               _cursor_stack.push (cursor);
+               set_canvas_cursor (cursor, false);
+       }
+}
+
+void
+Editor::pop_canvas_cursor ()
+{
+       if (!_cursor_stack.empty()) {
+               Gdk::Cursor* cursor = _cursor_stack.top ();
+               _cursor_stack.pop ();
+               set_canvas_cursor (cursor, false);
+       }
+}
+
 bool
 Editor::track_canvas_key_press (GdkEventKey*)
 {