Skip non active and hidden tracks with prev/next track. Also prevent ensuring the...
[ardour.git] / gtk2_ardour / editor_ops.cc
index c04bb792cfc9bb52191eb95178d6420f348de4fa..b4cb4c688c69f7bffc09f221971e715e4abfacda 100644 (file)
@@ -1714,7 +1714,6 @@ Editor::temporal_zoom_region (bool both_axes)
        nframes64_t end = 0;
        RegionSelection rs; 
        set<TimeAxisView*> tracks;
-       double top_y_position = DBL_MAX;
 
        get_regions_for_action (rs);
 
@@ -1733,10 +1732,6 @@ Editor::temporal_zoom_region (bool both_axes)
                }
 
                tracks.insert (&((*i)->get_time_axis_view()));
-
-               if ((*i)->get_time_axis_view().y_position < top_y_position) {
-                       top_y_position = (*i)->get_time_axis_view().y_position;
-               }
        }
 
        /* now comes an "interesting" hack ... make sure we leave a little space
@@ -1781,7 +1776,7 @@ Editor::temporal_zoom_region (bool both_axes)
        temporal_zoom_by_frame (start, end, "zoom to region");
 
        if (both_axes) {
-               uint32_t per_track_height = (uint32_t) floor ((canvas_height - 10.0) / tracks.size());
+               uint32_t per_track_height = (uint32_t) floor ((canvas_height - canvas_timebars_vsize - 10.0) / tracks.size());
                
                /* set visible track heights appropriately */
                
@@ -1802,7 +1797,7 @@ Editor::temporal_zoom_region (bool both_axes)
                no_route_list_redisplay = false;
                redisplay_route_list ();
 
-               vertical_adjustment.set_value (std::max (top_y_position - 5.0, 0.0));
+               vertical_adjustment.set_value (0);
                no_save_visual = false;
        }
 
@@ -1841,7 +1836,6 @@ Editor::temporal_zoom_session ()
        ENSURE_GUI_THREAD (mem_fun (*this, &Editor::temporal_zoom_session));
 
        if (session) {
-               last_canvas_frame = ((session->current_end_frame() - session->current_start_frame()) + (current_page_frames() / 24));
                temporal_zoom_by_frame (session->current_start_frame(), session->current_end_frame(), "zoom to session");
        }
 }
@@ -4647,6 +4641,28 @@ Editor::toggle_region_opaque ()
        }
 }
 
+void
+Editor::toggle_record_enable ()
+{
+       bool new_state;
+       bool first = true;
+       for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
+               RouteTimeAxisView *rtav = dynamic_cast<RouteTimeAxisView *>(*i);
+               if (!rtav)
+                       continue;
+               if (!rtav->is_track())
+                       continue;
+
+               if (first) {
+                       new_state = !rtav->track()->record_enabled();
+                       first = false;
+               }
+
+               rtav->track()->set_record_enable(new_state, this);
+       }
+}
+
+
 void
 Editor::set_fade_length (bool in)
 {
@@ -5131,17 +5147,26 @@ Editor::select_next_route()
 
        TimeAxisView* current = selection->tracks.front();
 
-       for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
-               if (*i == current) {
-                       ++i;
-                       if (i != track_views.end()) {
-                               selection->set (*i);
-                       } else {
-                               selection->set (*(track_views.begin()));
+       RouteUI *rui;
+       do {
+               for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
+                       if (*i == current) {
+                               ++i;
+                               if (i != track_views.end()) {
+                                       current = (*i);
+                               } else {
+                                       current = (*(track_views.begin()));
+                                       //selection->set (*(track_views.begin()));
+                               }
+                               break;
                        }
-                       break;
                }
-       }
+               rui = dynamic_cast<RouteUI *>(current);
+       } while ( current->hidden() || (rui != NULL && !rui->route()->active()));
+
+       selection->set(current);
+
+       ensure_track_visible(current);
 }
 
 void
@@ -5154,17 +5179,55 @@ Editor::select_prev_route()
 
        TimeAxisView* current = selection->tracks.front();
 
-       for (TrackViewList::reverse_iterator i = track_views.rbegin(); i != track_views.rend(); ++i) {
-               if (*i == current) {
-                       ++i;
-                       if (i != track_views.rend()) {
-                               selection->set (*i);
-                       } else {
-                               selection->set (*(track_views.rbegin()));
+       RouteUI *rui;
+       do {
+               for (TrackViewList::reverse_iterator i = track_views.rbegin(); i != track_views.rend(); ++i) {
+                       if (*i == current) {
+                               ++i;
+                               if (i != track_views.rend()) {
+                                       current = (*i);
+                               } else {
+                                       current = *(track_views.rbegin());
+                               }
+                               break;
                        }
-                       break;
                }
+               rui = dynamic_cast<RouteUI *>(current);
+       } while ( current->hidden() || (rui != NULL && !rui->route()->active()));
+
+       selection->set (current);
+
+       ensure_track_visible(current);
+}
+
+void
+Editor::ensure_track_visible(TimeAxisView *track)
+{
+       if (track->hidden())
+               return;
+
+       double current_view_min_y = vertical_adjustment.get_value();
+       double current_view_max_y = vertical_adjustment.get_value() + vertical_adjustment.get_page_size() - canvas_timebars_vsize;
+
+       double track_min_y = track->y_position;
+       double track_max_y = track->y_position + (double)track->effective_height;
+
+       if (track_min_y >= current_view_min_y &&
+            track_max_y <= current_view_max_y) {
+               return;
+       }
+
+       double new_value;
+
+       if (track_min_y < current_view_min_y) {
+               // Track is above the current view
+               new_value = track_min_y;
+       } else {
+               // Track is below the current view
+               new_value = track->y_position + (double)track->effective_height + canvas_timebars_vsize - vertical_adjustment.get_page_size();
        }
+
+       vertical_adjustment.set_value(new_value);
 }
 
 void
@@ -6023,16 +6086,51 @@ Editor::fit_tracks ()
        uint32_t h = (uint32_t) floor ((canvas_height - child_heights - canvas_timebars_vsize)/selection->tracks.size());
        double first_y_pos = DBL_MAX;
 
+       if (h < TimeAxisView::hSmall) {
+               MessageDialog msg (*this, _("There are too many selected tracks to fit in the current window"));
+               /* too small to be displayed */
+               return;
+       }
+
        undo_visual_stack.push_back (current_visual_state());
        
-       for (TrackSelection::iterator t = selection->tracks.begin(); t != selection->tracks.end(); ++t) {
-               (*t)->set_height (h);
-               first_y_pos = std::min ((*t)->y_position, first_y_pos);
+       /* operate on all tracks, hide unselected ones that are in the middle of selected ones */
+       
+       bool prev_was_selected = false;
+       bool is_selected = selection->selected (track_views.front());
+       bool next_is_selected;
+
+       for (TrackViewList::iterator t = track_views.begin(); t != track_views.end(); ++t) {
+
+               TrackViewList::iterator next;
+               
+               next = t;
+               ++next;
+               
+               if (next != track_views.end()) {
+                       next_is_selected = selection->selected (*next);
+               } else {
+                       next_is_selected = false;
+               }
+
+               if (is_selected) {
+                       (*t)->set_height (h);
+                       first_y_pos = std::min ((*t)->y_position, first_y_pos);
+               } else {
+                       if (prev_was_selected && next_is_selected) {
+                               hide_track_in_display (**t);
+                       }
+               }
+
+               prev_was_selected = is_selected;
+               is_selected = next_is_selected;
        }
+
        /* 
           set the controls_layout height now, because waiting for its size 
           request signal handler will cause the vertical adjustment setting to fail 
        */ 
+
        controls_layout.property_height () = full_canvas_height - canvas_timebars_vsize;
        vertical_adjustment.set_value (first_y_pos);