X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Feditor_summary.cc;h=dfbeccabfca0e09b85290890d0c75cbe7e47a664;hb=b998b8f761aaf1b8e61633f6054a6e9aa5d6c204;hp=e279da94d3f46c6b72960eefd61318ad99384b84;hpb=150d3fdfbfeabde96d528312aa22e839a5aa5f3e;p=ardour.git diff --git a/gtk2_ardour/editor_summary.cc b/gtk2_ardour/editor_summary.cc index e279da94d3..dfbeccabfc 100644 --- a/gtk2_ardour/editor_summary.cc +++ b/gtk2_ardour/editor_summary.cc @@ -50,12 +50,13 @@ EditorSummary::EditorSummary (Editor* e) _moved (false), _view_rectangle_x (0, 0), _view_rectangle_y (0, 0), - _zoom_dragging (false) + _zoom_dragging (false), + _old_follow_playhead (false) { Region::RegionPropertyChanged.connect (region_property_connection, invalidator (*this), boost::bind (&CairoWidget::set_dirty, this), gui_context()); _editor->playhead_cursor->PositionChanged.connect (position_connection, invalidator (*this), ui_bind (&EditorSummary::playhead_position_changed, this, _1), gui_context()); - add_events (Gdk::POINTER_MOTION_MASK); + add_events (Gdk::POINTER_MOTION_MASK); } /** Connect to a session. @@ -147,7 +148,7 @@ EditorSummary::render (cairo_t* cr) } /* compute start and end points for the summary */ - + framecnt_t const session_length = _session->current_end_frame() - _session->current_start_frame (); double const theoretical_start = _session->current_start_frame() - session_length * _overhang_fraction; _start = theoretical_start > 0 ? theoretical_start : 0; @@ -160,7 +161,7 @@ EditorSummary::render (cairo_t* cr) ++N; } } - + if (N == 0) { _track_height = 16; } else { @@ -188,7 +189,7 @@ EditorSummary::render (cairo_t* cr) cairo_move_to (cr, 0, y + _track_height / 2); cairo_line_to (cr, _width, y + _track_height / 2); cairo_stroke (cr); - + StreamView* s = (*i)->view (); if (s) { @@ -200,7 +201,7 @@ EditorSummary::render (cairo_t* cr) y + _track_height / 2 )); } - + y += _track_height; } @@ -274,25 +275,22 @@ EditorSummary::centre_on_click (GdkEventButton* ev) get_editor (&xr, &yr); double const w = xr.second - xr.first; - - xr.first = ev->x - w / 2; - xr.second = ev->x + w / 2; - - if (xr.first < 0) { - xr.first = 0; - xr.second = w; - } else if (xr.second > _width) { - xr.second = _width; - xr.first = _width - w; + double ex = ev->x - w / 2; + if (ex < 0) { + ex = 0; + } else if ((ex + w) > _width) { + ex = _width - w; } - double ey = summary_y_to_editor (ev->y); - ey -= (_editor->canvas_height() - _editor->get_canvas_timebars_vsize ()) / 2; + double const h = yr.second - yr.first; + double ey = ev->y - h / 2; if (ey < 0) { ey = 0; + } else if ((ey + h) > _height) { + ey = _height - h; } - - set_editor (xr, editor_y_to_summary (ey)); + + set_editor (ex, ey); } /** Handle a button press. @@ -322,7 +320,14 @@ EditorSummary::on_button_press_event (GdkEventButton* ev) _zoom_position = get_position (ev->x, ev->y); _zoom_dragging = true; _editor->_dragging_playhead = true; + _old_follow_playhead = _editor->follow_playhead (); + _editor->set_follow_playhead (false); + if (suspending_editor_updates ()) { + get_editor (&_pending_editor_x, &_pending_editor_y); + _pending_editor_changed = false; + } + } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::SecondaryModifier)) { /* secondary-modifier-click: locate playhead */ @@ -338,27 +343,56 @@ EditorSummary::on_button_press_event (GdkEventButton* ev) /* start a move drag */ + /* get the editor's state in case we are suspending updates */ + get_editor (&_pending_editor_x, &_pending_editor_y); + _pending_editor_changed = false; + _move_dragging = true; _moved = false; _editor->_dragging_playhead = true; + _old_follow_playhead = _editor->follow_playhead (); + _editor->set_follow_playhead (false); } } return true; } +/** @return true if we are currently suspending updates to the editor's viewport, + * which we do if configured to do so, and if in a drag of some kind. + */ +bool +EditorSummary::suspending_editor_updates () const +{ + return (!Config->get_update_editor_during_summary_drag () && (_zoom_dragging || _move_dragging)); +} + /** Fill in x and y with the editor's current viewable area in summary coordinates */ void EditorSummary::get_editor (pair* x, pair* y) const { assert (x); assert (y); - - x->first = (_editor->leftmost_position () - _start) * _x_scale; - x->second = x->first + _editor->current_page_frames() * _x_scale; - y->first = editor_y_to_summary (_editor->vertical_adjustment.get_value ()); - y->second = editor_y_to_summary (_editor->vertical_adjustment.get_value () + _editor->canvas_height() - _editor->get_canvas_timebars_vsize()); + if (suspending_editor_updates ()) { + + /* We are dragging, and configured not to update the editor window during drags, + so just return where the editor will be when the drag finishes. + */ + + *x = _pending_editor_x; + *y = _pending_editor_y; + + } else { + + /* Otherwise query the editor for its actual position */ + + x->first = (_editor->leftmost_position () - _start) * _x_scale; + x->second = x->first + _editor->current_page_frames() * _x_scale; + + y->first = editor_y_to_summary (_editor->vertical_adjustment.get_value ()); + y->second = editor_y_to_summary (_editor->vertical_adjustment.get_value () + _editor->canvas_height() - _editor->get_canvas_timebars_vsize()); + } } /** Get an expression of the position of a point with respect to the view rectangle */ @@ -375,7 +409,7 @@ EditorSummary::get_position (double x, double y) const int y_edge_size = (_view_rectangle_y.second - _view_rectangle_y.first) / 4; y_edge_size = min (y_edge_size, 8); y_edge_size = max (y_edge_size, 1); - + bool const near_left = (std::abs (x - _view_rectangle_x.first) < x_edge_size); bool const near_right = (std::abs (x - _view_rectangle_x.second) < x_edge_size); bool const near_top = (std::abs (y - _view_rectangle_y.first) < y_edge_size); @@ -458,6 +492,7 @@ EditorSummary::on_motion_notify_event (GdkEventMotion* ev) { pair xr = _start_editor_x; pair yr = _start_editor_y; + double x = _start_editor_x.first; double y = _start_editor_y.first; if (_move_dragging) { @@ -466,8 +501,7 @@ EditorSummary::on_motion_notify_event (GdkEventMotion* ev) /* don't alter x if we clicked outside and above or below the viewbox */ if (_start_position == INSIDE || _start_position == TO_LEFT_OR_RIGHT || _start_position == OTHERWISE_OUTSIDE) { - xr.first += ev->x - _start_mouse_x; - xr.second += ev->x - _start_mouse_x; + x += ev->x - _start_mouse_x; } /* don't alter y if we clicked outside and to the left or right of the viewbox */ @@ -475,16 +509,15 @@ EditorSummary::on_motion_notify_event (GdkEventMotion* ev) y += ev->y - _start_mouse_y; } - if (xr.first < 0) { - xr.second -= xr.first; - xr.first = 0; + if (x < 0) { + x = 0; } if (y < 0) { y = 0; } - set_editor (xr, y); + set_editor (x, y); set_cursor (_start_position); } else if (_zoom_dragging) { @@ -520,9 +553,17 @@ EditorSummary::on_motion_notify_event (GdkEventMotion* ev) bool EditorSummary::on_button_release_event (GdkEventButton*) { + bool const was_suspended = suspending_editor_updates (); + _move_dragging = false; _zoom_dragging = false; _editor->_dragging_playhead = false; + _editor->set_follow_playhead (_old_follow_playhead, false); + + if (was_suspended && _pending_editor_changed) { + set_editor (_pending_editor_x, _pending_editor_y); + } + return true; } @@ -534,6 +575,7 @@ EditorSummary::on_scroll_event (GdkEventScroll* ev) pair xr; pair yr; get_editor (&xr, &yr); + double x = xr.first; double y = yr.first; double amount = 8; @@ -549,11 +591,9 @@ EditorSummary::on_scroll_event (GdkEventScroll* ev) /* primary-wheel == left-right scrolling */ if (ev->direction == GDK_SCROLL_UP) { - xr.first += amount; - xr.second += amount; + x += amount; } else if (ev->direction == GDK_SCROLL_DOWN) { - xr.first -= amount; - xr.second -= amount; + x -= amount; } } else { @@ -563,24 +603,23 @@ EditorSummary::on_scroll_event (GdkEventScroll* ev) } else if (ev->direction == GDK_SCROLL_UP) { y -= amount; } else if (ev->direction == GDK_SCROLL_LEFT) { - xr.first -= amount; - xr.second -= amount; + x -= amount; } else if (ev->direction == GDK_SCROLL_RIGHT) { - xr.first += amount; - xr.second += amount; + x += amount; } } - set_editor (xr, y); + set_editor (x, y); return true; } -/** Set the editor to display a given x range and a y range with the top at a given position. - * The editor's x zoom is adjusted if necessary, but the y zoom is not changed. +/** Set the editor to display a x range with the left at a given position + * and a y range with the top at a given position. * x and y parameters are specified in summary coordinates. + * Zoom is not changed in either direction. */ void -EditorSummary::set_editor (pair const & x, double const y) +EditorSummary::set_editor (double const x, double const y) { if (_editor->pending_visual_change.idle_handler_id >= 0) { @@ -597,7 +636,23 @@ EditorSummary::set_editor (pair const & x, double const y) return; } - + + set_editor_x (x); + set_editor_y (y); +} + +/** Set the editor to display a given x range and a y range with the top at a given position. + * The editor's x zoom is adjusted if necessary, but the y zoom is not changed. + * x and y parameters are specified in summary coordinates. + */ +void +EditorSummary::set_editor (pair const x, double const y) +{ + if (_editor->pending_visual_change.idle_handler_id >= 0) { + /* see comment in other set_editor () */ + return; + } + set_editor_x (x); set_editor_y (y); } @@ -607,7 +662,7 @@ EditorSummary::set_editor (pair const & x, double const y) * x and y parameters are specified in summary coordinates. */ void -EditorSummary::set_editor (pair const & x, pair const & y) +EditorSummary::set_editor (pair const x, pair const y) { if (_editor->pending_visual_change.idle_handler_id >= 0) { /* see comment in other set_editor () */ @@ -618,23 +673,59 @@ EditorSummary::set_editor (pair const & x, pair c set_editor_y (y); } +/** Set the left of the x range visible in the editor. + * Caller should have checked that Editor::pending_visual_change.idle_handler_id is < 0 + * @param x new x left position in summary coordinates. + */ +void +EditorSummary::set_editor_x (double x) +{ + if (x < 0) { + x = 0; + } + + if (suspending_editor_updates ()) { + double const w = _pending_editor_x.second - _pending_editor_x.first; + _pending_editor_x.first = x; + _pending_editor_x.second = x + w; + _pending_editor_changed = true; + set_dirty (); + } else { + _editor->reset_x_origin (x / _x_scale + _start); + } +} + /** Set the x range visible in the editor. * Caller should have checked that Editor::pending_visual_change.idle_handler_id is < 0 * @param x new x range in summary coordinates. */ void -EditorSummary::set_editor_x (pair const & x) +EditorSummary::set_editor_x (pair x) { - _editor->reset_x_origin (x.first / _x_scale + _start); + if (x.first < 0) { + x.first = 0; + } - double const nx = ( - ((x.second - x.first) / _x_scale) / - _editor->frame_to_unit (_editor->current_page_frames()) - ); - - if (nx != _editor->get_current_zoom ()) { - _editor->reset_zoom (nx); - } + if (x.second < 0) { + x.second = x.first + 1; + } + + if (suspending_editor_updates ()) { + _pending_editor_x = x; + _pending_editor_changed = true; + set_dirty (); + } else { + _editor->reset_x_origin (x.first / _x_scale + _start); + + double const nx = ( + ((x.second - x.first) / _x_scale) / + _editor->frame_to_unit (_editor->current_page_frames()) + ); + + if (nx != _editor->get_current_zoom ()) { + _editor->reset_zoom (nx); + } + } } /** Set the top of the y range visible in the editor. @@ -647,18 +738,26 @@ EditorSummary::set_editor_y (double const y) double y1 = summary_y_to_editor (y); double const eh = _editor->canvas_height() - _editor->get_canvas_timebars_vsize (); double y2 = y1 + eh; - + double const full_editor_height = _editor->full_canvas_height - _editor->get_canvas_timebars_vsize(); if (y2 > full_editor_height) { y1 -= y2 - full_editor_height; } - + if (y1 < 0) { y1 = 0; } - _editor->reset_y_origin (y1); + if (suspending_editor_updates ()) { + double const h = _pending_editor_y.second - _pending_editor_y.first; + _pending_editor_y.first = y; + _pending_editor_y.second = y + h; + _pending_editor_changed = true; + set_dirty (); + } else { + _editor->reset_y_origin (y1); + } } /** Set the y range visible in the editor. This is achieved by scaling track heights, @@ -667,8 +766,15 @@ EditorSummary::set_editor_y (double const y) * @param y new editor range in summary coodinates. */ void -EditorSummary::set_editor_y (pair const & y) +EditorSummary::set_editor_y (pair const y) { + if (suspending_editor_updates ()) { + _pending_editor_y = y; + _pending_editor_changed = true; + set_dirty (); + return; + } + /* Compute current height of tracks between y.first and y.second. We add up the total height into `total_height' and the height of complete tracks into `scale height'. @@ -682,7 +788,7 @@ EditorSummary::set_editor_y (pair const & y) double partial_height = 0; /* Height of any tracks that are fully in the desired range */ double scale_height = 0; - + _editor->_routes->suspend_redisplay (); for (TrackViewList::const_iterator i = _editor->track_views.begin(); i != _editor->track_views.end(); ++i) { @@ -690,7 +796,7 @@ EditorSummary::set_editor_y (pair const & y) if ((*i)->hidden()) { continue; } - + double const h = (*i)->effective_height (); total_height += h; @@ -711,7 +817,7 @@ EditorSummary::set_editor_y (pair const & y) enough tracks to fill it. */ double const ch = min (total_height, _editor->canvas_height() - _editor->get_canvas_timebars_vsize()); - + /* hence required scale factor of the complete tracks to fit the required y range; the amount of space they should take up divided by the amount they currently take up. */ @@ -720,7 +826,7 @@ EditorSummary::set_editor_y (pair const & y) yc = y; /* Scale complete tracks within the range to make it fit */ - + for (TrackViewList::const_iterator i = _editor->track_views.begin(); i != _editor->track_views.end(); ++i) { if ((*i)->hidden()) { @@ -736,7 +842,7 @@ EditorSummary::set_editor_y (pair const & y) } _editor->_routes->resume_redisplay (); - + set_editor_y (y.first); } @@ -753,11 +859,11 @@ EditorSummary::summary_y_to_editor (double y) const { double ey = 0; for (TrackViewList::const_iterator i = _editor->track_views.begin (); i != _editor->track_views.end(); ++i) { - + if ((*i)->hidden()) { continue; } - + double const h = (*i)->effective_height (); if (y < _track_height) { /* in this track */ @@ -776,7 +882,7 @@ EditorSummary::editor_y_to_summary (double y) const { double sy = 0; for (TrackViewList::const_iterator i = _editor->track_views.begin (); i != _editor->track_views.end(); ++i) { - + if ((*i)->hidden()) { continue; }