a bit more styling for that lock dialog
[ardour.git] / gtk2_ardour / editor_ops.cc
index e6b4fee43ef733052142ba050813a517a41d6489..759c795e3852fd0b47bcc5c194d4b569bccff7bf 100644 (file)
@@ -57,6 +57,7 @@
 
 #include "canvas/canvas.h"
 
+#include "actions.h"
 #include "ardour_ui.h"
 #include "audio_region_view.h"
 #include "audio_streamview.h"
@@ -70,7 +71,6 @@
 #include "editor_drag.h"
 #include "editor_regions.h"
 #include "editor_routes.h"
-#include "gtk-custom-hruler.h"
 #include "gui_thread.h"
 #include "insert_time_dialog.h"
 #include "interthread_progress_window.h"
@@ -1333,23 +1333,26 @@ Editor::scroll_tracks_up_line ()
 bool
 Editor::scroll_down_one_track ()
 {
-       double vertical_pos = vertical_adjustment.get_value () + vertical_adjustment.get_page_size() - 1.0; 
-
        TrackViewList::reverse_iterator next = track_views.rend();
        std::pair<TimeAxisView*,double> res;
+       const double bottom_of_trackviews = vertical_adjustment.get_value() + vertical_adjustment.get_page_size() - 1;
 
        for (TrackViewList::reverse_iterator t = track_views.rbegin(); t != track_views.rend(); ++t) {
                if ((*t)->hidden()) {
                        continue;
                }
                
-               res = (*t)->covers_y_position (vertical_pos);
+               /* If this is the bottom visible trackview, we want to display
+                  the next one.
+               */
+
+               res = (*t)->covers_y_position (bottom_of_trackviews);
 
                if (res.first) {
                        break;
                }
 
-               next = t;
+               ++next; // moves "next" towards the "front" since it is a reverse iterator
        }
 
        /* move to the track below the first one that covers the */
@@ -1376,9 +1379,11 @@ Editor::scroll_up_one_track ()
                        continue;
                }
 
-               res = (*t)->covers_y_position(vertical_pos);
+               /* find the trackview at the top of the trackview group */
+               res = (*t)->covers_y_position (vertical_pos);
                
                if (res.first) {
+                       cerr << res.first->name() << " covers the top\n";
                        break;
                }
 
@@ -1458,8 +1463,23 @@ Editor::clamp_samples_per_pixel (framecnt_t& fpp) const
                clamped = true;
        }
 
-       if (max_framepos / fpp < 800) {
-               fpp = max_framepos / 800;
+       framecnt_t sr;
+
+       if (_session) {
+               sr = _session->frame_rate ();
+       } else {
+               sr = 48000;
+       }
+
+       const framecnt_t three_days = 3 * 24 * 60 * 60 * sr;
+       const framecnt_t lots_of_pixels = 4000;
+
+       /* if the zoom level is greater than what you'd get trying to display 3
+        * days of audio on a really big screen, scale it down.
+        */
+
+       if (fpp * lots_of_pixels > three_days) {
+               fpp = three_days / _track_canvas->width();
                clamped = true;
        }
 
@@ -5719,16 +5739,21 @@ Editor::select_prev_route()
 void
 Editor::ensure_track_visible(TimeAxisView *track)
 {
-       if (track->hidden())
+       if (track->hidden()) {
                return;
+       }
+
+       /* compute visible area of trackview group, as offsets from top of
+        * trackview group.
+        */
 
        double const current_view_min_y = vertical_adjustment.get_value();
-       double const current_view_max_y = vertical_adjustment.get_value() + vertical_adjustment.get_page_size();
+       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 (track_min_y >= current_view_min_y &&
+       if (track_min_y > current_view_min_y &&
            track_max_y <= current_view_max_y) {
                return;
        }
@@ -6860,7 +6885,13 @@ Editor::fit_tracks (TrackViewList & tracks)
                ++visible_tracks;
        }
 
-       uint32_t h = (uint32_t) floor ((_visible_canvas_height - child_heights) / visible_tracks);
+       /* compute the per-track height from:
+
+          total canvas visible height - 
+                 height that will be taken by visible children of selected
+                 tracks - height of the ruler/hscroll area 
+       */
+       uint32_t h = (uint32_t) floor ((_visible_canvas_height - (child_heights + _trackview_group->canvas_origin().y)) / visible_tracks);
        double first_y_pos = DBL_MAX;
 
        if (h < TimeAxisView::preset_height (HeightSmall)) {
@@ -6885,9 +6916,7 @@ Editor::fit_tracks (TrackViewList & tracks)
 
        /* operate on all tracks, hide unselected ones that are in the middle of selected ones */
 
-       bool prev_was_selected = false;
-       bool is_selected = tracks.contains (all.front());
-       bool next_is_selected;
+       bool within_selected = false;
 
        for (TrackViewList::iterator t = all.begin(); t != all.end(); ++t) {
 
@@ -6895,26 +6924,16 @@ Editor::fit_tracks (TrackViewList & tracks)
 
                next = t;
                ++next;
-
-               if (next != all.end()) {
-                       next_is_selected = tracks.contains (*next);
-               } else {
-                       next_is_selected = false;
-               }
-
+               
                if ((*t)->marked_for_display ()) {
-                       if (is_selected) {
+                       if (tracks.contains (*t)) { 
                                (*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);
-                               }
+                               within_selected = true;
+                       } else if (within_selected) {
+                               hide_track_in_display (*t);
                        }
                }
-
-               prev_was_selected = is_selected;
-               is_selected = next_is_selected;
        }
 
        /*
@@ -7098,3 +7117,33 @@ Editor::toggle_midi_input_active (bool flip_others)
        
        _session->set_exclusive_input_active (rl, onoff, flip_others);
 }
+
+void
+Editor::lock ()
+{
+       if (!lock_dialog) {
+               lock_dialog = new ArdourDialog (string_compose (_("%1: Locked"), PROGRAM_NAME), true);
+
+               Gtk::Image* padlock = manage (new Gtk::Image (::get_icon ("padlock_closed")));
+               lock_dialog->get_vbox()->pack_start (*padlock);
+
+               ArdourButton* b = manage (new ArdourButton);
+               b->set_name ("lock button");
+               b->set_markup (string_compose ("<span size=\"large\" weight=\"bold\">%1</span>", _("Click me to unlock")));
+               b->signal_clicked.connect (sigc::mem_fun (*this, &Editor::unlock));
+               lock_dialog->get_vbox()->pack_start (*b);
+               
+               lock_dialog->get_vbox()->show_all ();
+               lock_dialog->set_size_request (200, 200);
+       }
+       
+       ActionManager::disable_all_actions ();
+       lock_dialog->present ();
+}
+
+void
+Editor::unlock ()
+{
+       lock_dialog->hide ();
+       ActionManager::pop_action_state ();
+}