proper 1px track separator
[ardour.git] / gtk2_ardour / editor_canvas.cc
index 2f37a877ea71e20698a05ba466587ffbdccaf72e..66caeb7bc6d72ab55899873d6bb4f22320070943 100644 (file)
@@ -56,6 +56,7 @@
 
 using namespace std;
 using namespace ARDOUR;
+using namespace ARDOUR_UI_UTILS;
 using namespace PBD;
 using namespace Gtk;
 using namespace Glib;
@@ -804,26 +805,48 @@ Editor::entered_track_canvas (GdkEventCrossing */*ev*/)
 }
 
 void
-Editor::_ensure_time_axis_view_is_visible (const TimeAxisView& tav, bool at_top)
+Editor::ensure_time_axis_view_is_visible (TimeAxisView const & track, bool at_top)
 {
-       double begin = tav.y_position();
-       double v = vertical_adjustment.get_value ();
-
-       if (!at_top && (begin < v || begin + tav.current_height() > v + _visible_canvas_height)) {
-               /* try to put the TimeAxisView roughly central */
-               if (begin >= _visible_canvas_height/2.0) {
-                       begin -= _visible_canvas_height/2.0;
-               }
+       if (track.hidden()) {
+               return;
        }
 
-       /* Clamp the y pos so that we do not extend beyond the canvas full
-        * height. 
+       /* compute visible area of trackview group, as offsets from top of
+        * trackview group.
         */
-       if (_full_canvas_height - begin < _visible_canvas_height){
-               begin = _full_canvas_height - _visible_canvas_height;
+
+       double const current_view_min_y = vertical_adjustment.get_value();
+       double const current_view_max_y = current_view_min_y + vertical_adjustment.get_page_size();
+
+       double const track_min_y = track.y_position ();
+       double const track_max_y = track.y_position () + track.effective_height ();
+
+       if (!at_top && 
+           (track_min_y >= current_view_min_y &&
+            track_max_y < current_view_max_y)) {
+               /* already visible, and caller did not ask to place it at the
+                * top of the track canvas
+                */
+               return;
+       }
+
+       double new_value;
+
+       if (at_top) {
+               new_value = track_min_y;
+       } else {
+               if (track_min_y < current_view_min_y) {
+                       // Track is above the current view
+                       new_value = track_min_y;
+               } else if (track_max_y > current_view_max_y) {
+                       // Track is below the current view
+                       new_value = track.y_position () + track.effective_height() - vertical_adjustment.get_page_size();
+               } else {
+                       new_value = track_min_y;
+               }
        }
 
-       vertical_adjustment.set_value (begin);
+       vertical_adjustment.set_value(new_value);
 }
 
 /** Called when the main vertical_adjustment has changed */
@@ -867,7 +890,6 @@ Editor::color_handler()
        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());
 
        meter_bar->set_fill_color (ARDOUR_UI::config()->get_canvasvar_MeterBar());
        meter_bar->set_outline_color (ARDOUR_UI::config()->get_canvasvar_MarkerBarSeparator());
@@ -1094,6 +1116,10 @@ Editor::which_mode_cursor () const
                }
                break;
 
+       case MouseCut:
+               mode_cursor = _cursors->scissors;
+               break;
+                       
        case MouseObject:
                /* don't use mode cursor, pick a grabber cursor based on the item */
                break;
@@ -1169,11 +1195,9 @@ Editor::which_track_cursor () const
                case JOIN_OBJECT_RANGE_NONE:
                case JOIN_OBJECT_RANGE_OBJECT:
                        cursor = which_grabber_cursor ();
-                       cerr << "region use grabber\n";
                        break;
                case JOIN_OBJECT_RANGE_RANGE:
                        cursor = _cursors->selector;
-                       cerr << "region use selector\n";
                        break;
                }
        }
@@ -1203,8 +1227,6 @@ Editor::choose_canvas_cursor_on_entry (GdkEventCrossing* /*event*/, ItemType typ
 {
        Gdk::Cursor* cursor = 0;
 
-       cerr << "entered new item type " << enum_2_string (type) << endl;
-
        if (_drags->active()) {
                return;
        }
@@ -1277,10 +1299,12 @@ Editor::choose_canvas_cursor_on_entry (GdkEventCrossing* /*event*/, ItemType typ
                        cursor = _cursors->cross_hair;
                        break;
                case LeftFrameHandle:
-                       cursor = which_trim_cursor (true);
+                       if ( effective_mouse_mode() == MouseObject )  // (smart mode): if the user is in the top half, override the trim cursor, since they are in the range zone
+                               cursor = which_trim_cursor (true);  //alternatively, one could argue that we _should_ allow trims here, and disallow range selection
                        break;
                case RightFrameHandle:
-                       cursor = which_trim_cursor (false);
+                       if ( effective_mouse_mode() == MouseObject )  //see above
+                               cursor = which_trim_cursor (false);
                        break;
                case StartCrossFadeItem:
                        cursor = _cursors->fade_in;
@@ -1316,6 +1340,7 @@ Editor::choose_canvas_cursor_on_entry (GdkEventCrossing* /*event*/, ItemType typ
        case CdMarkerBarItem:
        case VideoBarItem:
        case TransportMarkerBarItem:
+       case DropZoneItem:
                cursor = which_grabber_cursor();
                break;
 
@@ -1327,3 +1352,13 @@ Editor::choose_canvas_cursor_on_entry (GdkEventCrossing* /*event*/, ItemType typ
                set_canvas_cursor (cursor, false);
        }
 }
+
+double
+Editor::trackviews_height() const
+{
+       if (!_trackview_group) {
+               return 0;
+       }
+
+       return _visible_canvas_height - _trackview_group->canvas_origin().y;
+}