X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Feditor_canvas.cc;h=3d763cbe568cdc7be7ddf85fcce6b9aee3d0abf3;hb=4e411dfd7bab6793426979fe005faf2435c0df0d;hp=73bc7d1884fe5a447c32035f6c634d07cdf7db11;hpb=becf857f48dd021307fca75082d29b95b4ffd539;p=ardour.git diff --git a/gtk2_ardour/editor_canvas.cc b/gtk2_ardour/editor_canvas.cc index 73bc7d1884..3d763cbe56 100644 --- a/gtk2_ardour/editor_canvas.cc +++ b/gtk2_ardour/editor_canvas.cc @@ -56,6 +56,7 @@ using namespace std; using namespace ARDOUR; +using namespace ARDOUR_UI_UTILS; using namespace PBD; using namespace Gtk; using namespace Glib; @@ -68,6 +69,11 @@ Editor::initialize_canvas () _track_canvas_viewport = new ArdourCanvas::GtkCanvasViewport (horizontal_adjustment, vertical_adjustment); _track_canvas = _track_canvas_viewport->canvas (); + /* scroll group for items that should not automatically scroll + * (e.g verbose cursor). It shares the canvas coordinate space. + */ + no_scroll_group = new ArdourCanvas::Container (_track_canvas->root()); + ArdourCanvas::ScrollGroup* hsg; ArdourCanvas::ScrollGroup* hg; ArdourCanvas::ScrollGroup* vg; @@ -101,7 +107,7 @@ Editor::initialize_canvas () } /*a group to hold global rects like punch/loop indicators */ - global_rect_group = new ArdourCanvas::Group (hv_scroll_group); + global_rect_group = new ArdourCanvas::Container (hv_scroll_group); CANVAS_DEBUG_NAME (global_rect_group, "global rect group"); transport_loop_range_rect = new ArdourCanvas::Rectangle (global_rect_group, ArdourCanvas::Rect (0.0, 0.0, 0.0, ArdourCanvas::COORD_MAX)); @@ -113,10 +119,10 @@ Editor::initialize_canvas () transport_punch_range_rect->hide(); /*a group to hold time (measure) lines */ - time_line_group = new ArdourCanvas::Group (hv_scroll_group); + time_line_group = new ArdourCanvas::Container (hv_scroll_group); CANVAS_DEBUG_NAME (time_line_group, "time line group"); - _trackview_group = new ArdourCanvas::Group (hv_scroll_group); + _trackview_group = new ArdourCanvas::Container (hv_scroll_group); CANVAS_DEBUG_NAME (_trackview_group, "Canvas TrackViews"); // used to show zoom mode active zooming @@ -131,30 +137,30 @@ Editor::initialize_canvas () /* a group to hold stuff while it gets dragged around. Must be the * uppermost (last) group with hv_scroll_group as a parent */ - _drag_motion_group = new ArdourCanvas::Group (hv_scroll_group); + _drag_motion_group = new ArdourCanvas::Container (hv_scroll_group); CANVAS_DEBUG_NAME (_drag_motion_group, "Canvas Drag Motion"); /* TIME BAR CANVAS */ - _time_markers_group = new ArdourCanvas::Group (h_scroll_group); + _time_markers_group = new ArdourCanvas::Container (h_scroll_group); CANVAS_DEBUG_NAME (_time_markers_group, "time bars"); - cd_marker_group = new ArdourCanvas::Group (_time_markers_group, ArdourCanvas::Duple (0.0, 0.0)); + cd_marker_group = new ArdourCanvas::Container (_time_markers_group, ArdourCanvas::Duple (0.0, 0.0)); CANVAS_DEBUG_NAME (cd_marker_group, "cd marker group"); /* the vide is temporarily placed a the same location as the cd_marker_group, but is moved later. */ - videotl_group = new ArdourCanvas::Group (_time_markers_group, ArdourCanvas::Duple(0.0, 0.0)); + videotl_group = new ArdourCanvas::Container (_time_markers_group, ArdourCanvas::Duple(0.0, 0.0)); CANVAS_DEBUG_NAME (videotl_group, "videotl group"); - marker_group = new ArdourCanvas::Group (_time_markers_group, ArdourCanvas::Duple (0.0, timebar_height + 1.0)); + marker_group = new ArdourCanvas::Container (_time_markers_group, ArdourCanvas::Duple (0.0, timebar_height + 1.0)); CANVAS_DEBUG_NAME (marker_group, "marker group"); - transport_marker_group = new ArdourCanvas::Group (_time_markers_group, ArdourCanvas::Duple (0.0, (timebar_height * 2.0) + 1.0)); + transport_marker_group = new ArdourCanvas::Container (_time_markers_group, ArdourCanvas::Duple (0.0, (timebar_height * 2.0) + 1.0)); CANVAS_DEBUG_NAME (transport_marker_group, "transport marker group"); - range_marker_group = new ArdourCanvas::Group (_time_markers_group, ArdourCanvas::Duple (0.0, (timebar_height * 3.0) + 1.0)); + range_marker_group = new ArdourCanvas::Container (_time_markers_group, ArdourCanvas::Duple (0.0, (timebar_height * 3.0) + 1.0)); CANVAS_DEBUG_NAME (range_marker_group, "range marker group"); - tempo_group = new ArdourCanvas::Group (_time_markers_group, ArdourCanvas::Duple (0.0, (timebar_height * 4.0) + 1.0)); + tempo_group = new ArdourCanvas::Container (_time_markers_group, ArdourCanvas::Duple (0.0, (timebar_height * 4.0) + 1.0)); CANVAS_DEBUG_NAME (tempo_group, "tempo group"); - meter_group = new ArdourCanvas::Group (_time_markers_group, ArdourCanvas::Duple (0.0, (timebar_height * 5.0) + 1.0)); + meter_group = new ArdourCanvas::Container (_time_markers_group, ArdourCanvas::Duple (0.0, (timebar_height * 5.0) + 1.0)); CANVAS_DEBUG_NAME (meter_group, "meter group"); meter_bar = new ArdourCanvas::Rectangle (meter_group, ArdourCanvas::Rect (0.0, 0.0, ArdourCanvas::COORD_MAX, timebar_height)); @@ -413,7 +419,7 @@ Editor::drop_paths_part_two (const vector& paths, framepos_t frame, doub } - std::pair const tvp = trackview_by_y_position (ypos); + std::pair const tvp = trackview_by_y_position (ypos, false); if (tvp.first == 0) { /* drop onto canvas background: create new tracks */ @@ -511,14 +517,11 @@ Editor::maybe_autoscroll (bool allow_horiz, bool allow_vert, bool from_headers) ArdourCanvas::Rect scrolling_boundary; Gtk::Allocation alloc; - int cx, cy; if (from_headers) { alloc = controls_layout.get_allocation (); } 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. @@ -575,12 +578,12 @@ Editor::autoscroll_canvas () Gdk::ModifierType mask; frameoffset_t dx = 0; bool no_stop = false; - bool y_motion = false; get_window()->get_pointer (x, y, mask); VisualChange vc; bool vertical_motion = false; + bool y_motion = false; if (autoscroll_horizontal_allowed) { @@ -638,14 +641,14 @@ Editor::autoscroll_canvas () /* scroll to make higher tracks visible */ if (autoscroll_cnt && (autoscroll_cnt % speed_factor == 0)) { - y_motion = scroll_up_one_track (); + 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 (); + scroll_down_one_track (); vertical_motion = true; } } @@ -799,26 +802,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 */ @@ -862,7 +887,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()); @@ -982,8 +1006,8 @@ Editor::set_canvas_cursor (Gdk::Cursor* cursor, bool save) Glib::RefPtr win = _track_canvas->get_window(); - if (win) { - _track_canvas->get_window()->set_cursor (*cursor); + if (win && cursor) { + win->set_cursor (*cursor); } } @@ -1089,6 +1113,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; @@ -1153,7 +1181,7 @@ Editor::which_mode_cursor () const } Gdk::Cursor* -Editor::which_region_cursor () const +Editor::which_track_cursor () const { Gdk::Cursor* cursor = 0; @@ -1164,11 +1192,9 @@ Editor::which_region_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; } } @@ -1198,8 +1224,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; } @@ -1215,7 +1239,9 @@ Editor::choose_canvas_cursor_on_entry (GdkEventCrossing* /*event*/, ItemType typ case RegionViewNameHighlight: case RegionViewName: case WaveItem: - cursor = which_region_cursor (); + case StreamItem: + case AutomationTrackItem: + cursor = which_track_cursor (); break; case PlayheadCursorItem: switch (_edit_point) { @@ -1240,11 +1266,10 @@ Editor::choose_canvas_cursor_on_entry (GdkEventCrossing* /*event*/, ItemType typ cursor = _cursors->cross_hair; break; case StartSelectionTrimItem: + cursor = _cursors->left_side_trim; break; case EndSelectionTrimItem: - break; - case AutomationTrackItem: - cursor = _cursors->cross_hair; + cursor = _cursors->right_side_trim; break; case FadeInItem: cursor = _cursors->fade_in; @@ -1271,10 +1296,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; @@ -1310,6 +1337,7 @@ Editor::choose_canvas_cursor_on_entry (GdkEventCrossing* /*event*/, ItemType typ case CdMarkerBarItem: case VideoBarItem: case TransportMarkerBarItem: + case DropZoneItem: cursor = which_grabber_cursor(); break; @@ -1321,3 +1349,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; +}