merge from 2.0-ongoing by hand, minus key binding editor
[ardour.git] / gtk2_ardour / editor_rulers.cc
index ecf7f0b2631dcfd20599cb69c4c1d26825418adb..88ff3a0c1e9452b7c991e3da4ffe5248352a388e 100644 (file)
@@ -15,7 +15,6 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id$
 */
 
 #include <cstdio> // for sprintf, grrr 
@@ -56,6 +55,11 @@ Editor::initialize_rulers ()
        ruler_editor = this;
        ruler_grabbed_widget = 0;
        
+       _ruler_separator = new Gtk::HSeparator();
+       _ruler_separator->set_size_request(-1, 2);
+       _ruler_separator->set_name("TimebarPadding");
+       _ruler_separator->show();
+       
        _smpte_ruler = gtk_custom_hruler_new ();
        smpte_ruler = Glib::wrap (_smpte_ruler);
        smpte_ruler->set_name ("SMPTERuler");
@@ -138,6 +142,40 @@ Editor::ruler_button_press (GdkEventButton* ev)
                ruler_grabbed_widget = grab_widget;
        }
 
+       gint x,y;
+       Gdk::ModifierType state;
+
+       /* need to use the correct x,y, the event lies */
+       time_canvas_event_box.get_window()->get_pointer (x, y, state);
+
+       nframes_t where = leftmost_frame + pixel_to_frame (x);
+
+       switch (ev->button) {
+       case 1:
+               // Since we will locate the playhead on button release, cancel any running
+               // auditions.
+               if (session->is_auditioning()) {
+                       session->cancel_audition ();
+               }
+               /* playhead cursor */
+               snap_to (where);
+               playhead_cursor->set_position (where);
+               _dragging_playhead = true;
+               break;
+
+       case 2:
+               /* edit cursor */
+               if (snap_type != Editing::SnapToEditCursor) {
+                       snap_to (where);
+               }
+               edit_cursor->set_position (where);
+               edit_cursor_clock.set (where);
+               break;
+
+       default:
+               break;
+       }
+
        return TRUE;
 }
 
@@ -150,14 +188,12 @@ Editor::ruler_button_release (GdkEventButton* ev)
        /* need to use the correct x,y, the event lies */
        time_canvas_event_box.get_window()->get_pointer (x, y, state);
 
-
        ruler_pressed_button = 0;
        
        if (session == 0) {
                return FALSE;
        }
 
-       hide_verbose_canvas_cursor();
        stop_canvas_autoscroll();
        
        nframes_t where = leftmost_frame + pixel_to_frame (x);
@@ -165,6 +201,7 @@ Editor::ruler_button_release (GdkEventButton* ev)
        switch (ev->button) {
        case 1:
                /* transport playhead */
+               _dragging_playhead = false;
                snap_to (where);
                session->request_locate (where);
                break;
@@ -216,7 +253,7 @@ Editor::ruler_mouse_motion (GdkEventMotion* ev)
                return FALSE;
        }
 
-       double wcx=0,wcy=0;
+               double wcx=0,wcy=0;
        double cx=0,cy=0;
 
        gint x,y;
@@ -225,15 +262,14 @@ Editor::ruler_mouse_motion (GdkEventMotion* ev)
        /* need to use the correct x,y, the event lies */
        time_canvas_event_box.get_window()->get_pointer (x, y, state);
 
-       
+
        track_canvas.c2w (x, y, wcx, wcy);
        track_canvas.w2c (wcx, wcy, cx, cy);
        
        nframes_t where = leftmost_frame + pixel_to_frame (x);
 
-       /// ripped from maybe_autoscroll
-       nframes_t one_page = (nframes_t) rint (canvas_width * frames_per_unit);
-       nframes_t rightmost_frame = leftmost_frame + one_page;
+       /// ripped from maybe_autoscroll, and adapted to work here
+       nframes_t rightmost_frame = leftmost_frame + current_page_frames ();
 
        jack_nframes_t frame = pixel_to_frame (cx);
 
@@ -273,15 +309,14 @@ Editor::ruler_mouse_motion (GdkEventMotion* ev)
                break;
        }
 
-       if (cursor)
-       {
+       if (cursor) {
                cursor->set_position (where);
                
                if (cursor == edit_cursor) {
                        edit_cursor_clock.set (where);
+               } else if (cursor == playhead_cursor) {
+                       UpdateAllTransportClocks (cursor->current_frame);
                }
-               
-               show_verbose_time_cursor (where, 10, cx, 0);
        }
        
        return TRUE;
@@ -311,11 +346,13 @@ Editor::popup_ruler_menu (nframes_t where, ItemType t)
        case MarkerBarItem:
                ruler_items.push_back (MenuElem (_("New location marker"), bind ( mem_fun(*this, &Editor::mouse_add_new_marker), where)));
                ruler_items.push_back (MenuElem (_("Clear all locations"), mem_fun(*this, &Editor::clear_markers)));
+               ruler_items.push_back (MenuElem (_("Unhide locations"), mem_fun(*this, &Editor::unhide_markers)));
                ruler_items.push_back (SeparatorElem ());
                break;
        case RangeMarkerBarItem:
                //ruler_items.push_back (MenuElem (_("New Range")));
                ruler_items.push_back (MenuElem (_("Clear all ranges"), mem_fun(*this, &Editor::clear_ranges)));
+               ruler_items.push_back (MenuElem (_("Unhide ranges"), mem_fun(*this, &Editor::unhide_ranges)));
                ruler_items.push_back (SeparatorElem ());
 
                break;
@@ -345,7 +382,7 @@ Editor::popup_ruler_menu (nframes_t where, ItemType t)
                mitem->set_active(true);
        }
 
-       ruler_items.push_back (CheckMenuElem (X_("SMPTE"), bind (mem_fun(*this, &Editor::ruler_toggled), (int)ruler_metric_smpte)));
+       ruler_items.push_back (CheckMenuElem (_("Timecode"), bind (mem_fun(*this, &Editor::ruler_toggled), (int)ruler_metric_smpte)));
        mitem = (CheckMenuItem *) &ruler_items.back(); 
        if (ruler_shown[ruler_metric_smpte]) {
                mitem->set_active(true);
@@ -395,7 +432,7 @@ Editor::popup_ruler_menu (nframes_t where, ItemType t)
                mitem->set_active(true);
        }
        
-        editor_ruler_menu->popup (1, 0);
+        editor_ruler_menu->popup (1, gtk_get_current_event_time());
 
        no_ruler_shown_update = false;
 }
@@ -441,7 +478,7 @@ Editor::store_ruler_visibility ()
        session->add_extra_xml (*node);
        session->set_dirty ();
 }
+
 void 
 Editor::restore_ruler_visibility ()
 {
@@ -572,8 +609,9 @@ Editor::update_ruler_visibility ()
        bbt_ruler->signal_motion_notify_event().connect (mem_fun(*this, &Editor::ruler_mouse_motion));
        frames_ruler->signal_motion_notify_event().connect (mem_fun(*this, &Editor::ruler_mouse_motion));
        minsec_ruler->signal_motion_notify_event().connect (mem_fun(*this, &Editor::ruler_mouse_motion));
-
        
+       ruler_children.insert (canvaspos, Element(*_ruler_separator, PACK_SHRINK, PACK_START));
+
        if (ruler_shown[ruler_metric_minsec]) {
                lab_children.push_back (Element(minsec_label, PACK_SHRINK, PACK_START));
                ruler_children.insert (canvaspos, Element(*minsec_ruler, PACK_SHRINK, PACK_START));
@@ -598,7 +636,7 @@ Editor::update_ruler_visibility ()
                visible_timebars++;
        }
 
-       double tbpos = 0.0;
+       double tbpos = 1.0;
        double old_unit_pos ;
        
        if (ruler_shown[ruler_time_meter]) {
@@ -677,10 +715,10 @@ Editor::update_ruler_visibility ()
        
        update_fixed_rulers();
        //update_tempo_based_rulers();
-       tempo_map_changed(Change (0));
+       redisplay_tempo (false);
 
        time_canvas_event_box.show_all();
-       time_button_event_box.show_all();
+       time_button_frame.show_all();
 }
 
 void
@@ -692,12 +730,7 @@ Editor::update_just_smpte ()
                return;
        }
 
-       /* XXX Note the potential loss of accuracy here as we convert from
-          an uint32_t (or larger) to a float ... what to do ?
-       */
-
-       nframes_t page = (nframes_t) floor (canvas_width * frames_per_unit);
-       nframes_t rightmost_frame = leftmost_frame + page;
+       nframes_t rightmost_frame = leftmost_frame + current_page_frames();
 
        if (ruler_shown[ruler_metric_smpte]) {
                gtk_custom_ruler_set_range (GTK_CUSTOM_RULER(_smpte_ruler), leftmost_frame, rightmost_frame,
@@ -714,17 +747,11 @@ Editor::update_fixed_rulers ()
                return;
        }
 
-       /* XXX Note the potential loss of accuracy here as we convert from
-          an uint32_t (or larger) to a float ... what to do ?
-       */
-
-       nframes_t page = (nframes_t) floor (canvas_width * frames_per_unit);
-
        ruler_metrics[ruler_metric_smpte].units_per_pixel = frames_per_unit;
        ruler_metrics[ruler_metric_frames].units_per_pixel = frames_per_unit;
        ruler_metrics[ruler_metric_minsec].units_per_pixel = frames_per_unit;
 
-       rightmost_frame = leftmost_frame + page;
+       rightmost_frame = leftmost_frame + current_page_frames ();
 
        /* these force a redraw, which in turn will force execution of the metric callbacks
           to compute the relevant ticks to display.
@@ -753,15 +780,10 @@ Editor::update_tempo_based_rulers ()
                return;
        }
 
-       /* XXX Note the potential loss of accuracy here as we convert from
-          an uint32_t (or larger) to a float ... what to do ?
-       */
-
-       nframes_t page = (nframes_t) floor (canvas_width * frames_per_unit);
        ruler_metrics[ruler_metric_bbt].units_per_pixel = frames_per_unit;
 
        if (ruler_shown[ruler_metric_bbt]) {
-               gtk_custom_ruler_set_range (GTK_CUSTOM_RULER(_bbt_ruler), leftmost_frame, leftmost_frame+page, 
+               gtk_custom_ruler_set_range (GTK_CUSTOM_RULER(_bbt_ruler), leftmost_frame, leftmost_frame+current_page_frames(),
                                            leftmost_frame, session->current_end_frame());
        }
 }
@@ -827,7 +849,7 @@ Editor::metric_get_smpte (GtkCustomRulerMark **marks, gdouble lower, gdouble upp
        if (range < (2 * session->frames_per_smpte_frame())) { /* 0 - 2 frames */
                show_bits = true;
                mark_modulo = 20;
-               nmarks = 1 + 160;
+               nmarks = 1 + (2 * Config->get_subframes_per_frame());
        } else if (range <= (fr / 4)) { /* 2 frames - 0.250 second */
                show_frames = true;
                mark_modulo = 1;
@@ -1043,13 +1065,12 @@ Editor::metric_get_bbt (GtkCustomRulerMark **marks, gdouble lower, gdouble upper
        uint32_t magic_accent_number = 1;
        gint nmarks;
         char buf[64];
-        gint n;
+        gint  n = 0;
        nframes_t pos;
        bool bar_helper_on = true;
        
        BBT_Time next_beat;
        nframes_t next_beat_pos;
-       nframes_t ilower = (nframes_t) floor (lower);
 
        if ((desirable_marks = maxchars / 7) == 0) {
                return 0;
@@ -1091,7 +1112,7 @@ Editor::metric_get_bbt (GtkCustomRulerMark **marks, gdouble lower, gdouble upper
        beats = current_bbt_points->size() - bars;
 
        /*Only show the bar helper if there aren't many bars on the screen */
-       if (bars > 2) {
+       if (bars > 1) {
                bar_helper_on = false;
        }
 
@@ -1108,11 +1129,12 @@ Editor::metric_get_bbt (GtkCustomRulerMark **marks, gdouble lower, gdouble upper
                double position_of_helper;
                bool i_am_accented = false;
                bool we_need_ticks = false;
+               bool helper_active = false;
        
-               position_of_helper = ilower + (30 * Editor::get_current_zoom ());
+               position_of_helper = lower + (30 * Editor::get_current_zoom ());
 
                if (desirable_marks >= (beats)) {
-                       nmarks = ((beats + 1) * bbt_beat_subdivision) + 1;
+                       nmarks = (beats * bbt_beat_subdivision) + 1;
                        we_need_ticks = true;
                } else {
                        nmarks = beats + 1;
@@ -1121,19 +1143,23 @@ Editor::metric_get_bbt (GtkCustomRulerMark **marks, gdouble lower, gdouble upper
                *marks = (GtkCustomRulerMark *) g_malloc (sizeof(GtkCustomRulerMark) * nmarks);
 
                (*marks)[0].label = g_strdup(" ");
-               (*marks)[0].position = ilower;
+               (*marks)[0].position = lower;
                (*marks)[0].style = GtkCustomRulerMarkMicro;
                
-               for (n = 1,   i = current_bbt_points->begin(); n < nmarks && i != current_bbt_points->end(); i++) {
+               for (n = 1,   i = current_bbt_points->begin(); n < nmarks && i != current_bbt_points->end(); ++i) {
 
-                       if ((*i).frame < ilower && (bar_helper_on)) {
+                       if ((*i).frame < lower && (bar_helper_on)) {
                                        snprintf (buf, sizeof(buf), "<%" PRIu32 "|%" PRIu32, (*i).bar, (*i).beat);
                                        (*marks)[0].label = g_strdup (buf); 
+                                       helper_active = true;
                        } else {
 
                          if ((*i).type == TempoMap::Bar)  {
-                           (((*i).frame < position_of_helper) && bar_helper_on) ?
-                             snprintf (buf, sizeof(buf), " ") : snprintf (buf, sizeof(buf), "%" PRIu32, (*i).bar);
+                           if (((*i).frame < position_of_helper) && helper_active) {
+                             snprintf (buf, sizeof(buf), " ");
+                           } else {
+                             snprintf (buf, sizeof(buf), "%" PRIu32, (*i).bar);
+                           }
                            (*marks)[n].label = g_strdup (buf);
                            (*marks)[n].position = (*i).frame;
                            (*marks)[n].style = GtkCustomRulerMarkMajor;
@@ -1157,7 +1183,7 @@ Editor::metric_get_bbt (GtkCustomRulerMark **marks, gdouble lower, gdouble upper
 
                        /* Add the tick marks */
 
-                       if (we_need_ticks && (*i).type != TempoMap::Bar) {
+                       if (we_need_ticks && (*i).type == TempoMap::Beat) {
 
                                /* Find the next beat */
 
@@ -1225,14 +1251,14 @@ Editor::metric_get_bbt (GtkCustomRulerMark **marks, gdouble lower, gdouble upper
 
                /* we're in bar land */
 
-               if (desirable_marks < (uint32_t) (bars / 256)) {
+               if (desirable_marks < (bars / 256)) {
                        nmarks = 1;
                        *marks = (GtkCustomRulerMark *) g_malloc (sizeof(GtkCustomRulerMark) * nmarks);
                        snprintf (buf, sizeof(buf), "too many bars... (currently %" PRIu32 ")", bars );
                        (*marks)[0].style = GtkCustomRulerMarkMajor;
                        (*marks)[0].label = g_strdup (buf);
-                       (*marks)[0].position = ilower;
-               } else if (desirable_marks < (uint32_t) (nmarks = (gint) (bars / 64))) {
+                       (*marks)[0].position = lower;
+               } else if (desirable_marks < (uint32_t)(nmarks = (gint) (bars / 64) + 1)) {
                        *marks = (GtkCustomRulerMark *) g_malloc (sizeof(GtkCustomRulerMark) * nmarks);
                        for (n = 0,   i = current_bbt_points->begin(); i != current_bbt_points->end() && n < nmarks; i++) {
                                if ((*i).type == TempoMap::Bar)  {
@@ -1254,7 +1280,7 @@ Editor::metric_get_bbt (GtkCustomRulerMark **marks, gdouble lower, gdouble upper
                                        }
                                }
                        }
-               } else if (desirable_marks < (uint32_t) (nmarks = (gint)(bars / 16))) {
+               } else if (desirable_marks < (uint32_t)(nmarks = (bars / 16) + 1)) {
                        *marks = (GtkCustomRulerMark *) g_malloc (sizeof(GtkCustomRulerMark) * nmarks);
                        for (n = 0,  i = current_bbt_points->begin(); i != current_bbt_points->end() && n < nmarks; i++) {
                                if ((*i).type == TempoMap::Bar)  {
@@ -1276,7 +1302,7 @@ Editor::metric_get_bbt (GtkCustomRulerMark **marks, gdouble lower, gdouble upper
                                        }
                                }
                        }
-               } else if (desirable_marks < (uint32_t) (nmarks = (gint)(bars / 4))){
+               } else if (desirable_marks < (uint32_t)(nmarks = (bars / 4) + 1)){
                        *marks = (GtkCustomRulerMark *) g_malloc (sizeof(GtkCustomRulerMark) * nmarks);
                        for (n = 0,   i = current_bbt_points->begin(); i != current_bbt_points->end() && n < nmarks; ++i) {
                                if ((*i).type == TempoMap::Bar)  {
@@ -1299,8 +1325,8 @@ Editor::metric_get_bbt (GtkCustomRulerMark **marks, gdouble lower, gdouble upper
                                }
                        }
                } else {
-                       nmarks = bars;
-                       *marks = (GtkCustomRulerMark *) g_malloc (sizeof(GtkCustomRulerMark) * nmarks);
+                       nmarks = bars + 1;
+                       *marks = (GtkCustomRulerMark *) g_malloc (sizeof(GtkCustomRulerMark) * nmarks );
                        for (n = 0,  i = current_bbt_points->begin(); i != current_bbt_points->end() && n < nmarks; i++) {
                                if ((*i).type == TempoMap::Bar)  {
                                        if ((*i).bar % 4 == 1) {
@@ -1320,7 +1346,7 @@ Editor::metric_get_bbt (GtkCustomRulerMark **marks, gdouble lower, gdouble upper
                                }
                        }
                }
-               return nmarks;
+               return n;
        }
 }