+ /* 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'.
+ */
+
+ /* Copy of target range for use below */
+ pair<double, double> yc = y;
+ /* Total height of all tracks */
+ double total_height = 0;
+ /* Height of any parts of tracks that aren't fully in the desired range */
+ 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) {
+
+ if ((*i)->hidden()) {
+ continue;
+ }
+
+ double const h = (*i)->effective_height ();
+ total_height += h;
+
+ if (yc.first > 0 && yc.first < _track_height) {
+ partial_height += (_track_height - yc.first) * h / _track_height;
+ } else if (yc.first <= 0 && yc.second >= _track_height) {
+ scale_height += h;
+ } else if (yc.second > 0 && yc.second < _track_height) {
+ partial_height += yc.second * h / _track_height;
+ break;
+ }
+
+ yc.first -= _track_height;
+ yc.second -= _track_height;
+ }
+
+ /* Height that we will use for scaling; use the whole editor height unless there are not
+ 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.
+ */
+ double const scale = (ch - partial_height) / scale_height;
+
+ 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()) {
+ continue;
+ }
+
+ if (yc.first <= 0 && yc.second >= _track_height) {
+ (*i)->set_height (max (TimeAxisView::preset_height (HeightSmall), (uint32_t) ((*i)->effective_height() * scale)));
+ }
+
+ yc.first -= _track_height;
+ yc.second -= _track_height;
+ }
+
+ _editor->_routes->resume_redisplay ();
+
+ set_editor_y (y.first);
+}
+
+void
+EditorSummary::playhead_position_changed (framepos_t p)
+{
+ int const o = int (_last_playhead);
+ int const n = int (playhead_frame_to_position (p));
+ if (_session && o != n) {
+ int a = max(2, min (o, n));
+ int b = max (o, n);
+ set_overlays_dirty (a - 2, 0, b + 2, get_height ());
+ }
+}
+
+double
+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 */
+ return ey + y * h / _track_height;
+ }
+
+ ey += h;
+ y -= _track_height;
+ }
+
+ return ey;
+}
+
+double
+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;
+ }
+
+ double const h = (*i)->effective_height ();
+ if (y < h) {
+ /* in this track */
+ return sy + y * _track_height / h;
+ }
+
+ sy += _track_height;
+ y -= h;
+ }
+
+ return sy;
+}
+
+void
+EditorSummary::routes_added (list<RouteTimeAxisView*> const & r)
+{
+ for (list<RouteTimeAxisView*>::const_iterator i = r.begin(); i != r.end(); ++i) {
+ /* Connect to gui_changed() on the route so that we know when their colour has changed */
+ (*i)->route()->gui_changed.connect (*this, invalidator (*this), boost::bind (&EditorSummary::route_gui_changed, this, _1), gui_context ());
+ boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> ((*i)->route ());
+ if (tr) {
+ tr->PlaylistChanged.connect (*this, invalidator (*this), boost::bind (&CairoWidget::set_dirty, this), gui_context ());
+ }
+ }
+
+ set_dirty ();
+}
+
+void
+EditorSummary::route_gui_changed (string c)
+{
+ if (c == "color") {
+ set_dirty ();
+ }
+}
+
+double
+EditorSummary::playhead_frame_to_position (framepos_t t) const
+{
+ return (t - _start) * _x_scale;
+}
+
+framepos_t
+EditorSummary::position_to_playhead_frame_to_position (double pos) const
+{
+ return _start + (pos * _x_scale);
+}