new_grid: Add options for rulers_follow_grid and grid_follows_internal
[ardour.git] / gtk2_ardour / editor.cc
index 9fda261113febd6af23ff1931485f81d447ca4dc..a8b40087382f6d0e0caa3395ade4727822efd73c 100644 (file)
@@ -79,6 +79,7 @@
 #include "ardour/vca.h"
 
 #include "canvas/debug.h"
+#include "canvas/note.h"
 #include "canvas/text.h"
 
 #include "widgets/ardour_spacer.h"
@@ -181,7 +182,7 @@ static const gchar *_grid_type_strings[] = {
        N_("1/28 (32nd septuplet)"),
        N_("Timecode"),
        N_("MinSec"),
-       N_("Samples"),
+       N_("CD Frames"),
        0
 };
 
@@ -698,14 +699,14 @@ Editor::Editor ()
        VBox* summary_arrows_right = manage (new VBox);
        summary_arrows_right->pack_start (*summary_arrow_right);
 
-       Frame* summary_sample = manage (new Frame);
-       summary_sample->set_shadow_type (Gtk::SHADOW_ETCHED_IN);
+       Frame* summary_frame = manage (new Frame);
+       summary_frame->set_shadow_type (Gtk::SHADOW_ETCHED_IN);
 
-       summary_sample->add (*_summary);
-       summary_sample->show ();
+       summary_frame->add (*_summary);
+       summary_frame->show ();
 
        _summary_hbox.pack_start (*summary_arrows_left, false, false);
-       _summary_hbox.pack_start (*summary_sample, true, true);
+       _summary_hbox.pack_start (*summary_frame, true, true);
        _summary_hbox.pack_start (*summary_arrows_right, false, false);
 
        if (!ARDOUR::Profile->get_trx()) {
@@ -2162,9 +2163,9 @@ Editor::grid_musical() const
        case GridTypeBar:
                return true;
        case GridTypeNone:
-       case GridTypeSmpte:
+       case GridTypeTimecode:
        case GridTypeMinSec:
-       case GridTypeSamples:
+       case GridTypeCDFrame:
                return false;
        }
        return false;
@@ -2174,9 +2175,9 @@ bool
 Editor::grid_nonmusical() const
 {
        switch (_grid_type) {
-       case GridTypeSmpte:
+       case GridTypeTimecode:
        case GridTypeMinSec:
-       case GridTypeSamples:
+       case GridTypeCDFrame:
                return true;
        case GridTypeBeatDiv32:
        case GridTypeBeatDiv28:
@@ -2215,7 +2216,7 @@ Editor::set_grid_to (GridType gt)
 
        unsigned int grid_ind = (unsigned int)gt;
 
-       if (internal_editing()) {
+       if (internal_editing() && UIConfiguration::instance().get_grid_follows_internal()) {
                internal_grid_type = gt;
        } else {
                pre_internal_grid_type = gt;
@@ -2235,41 +2236,48 @@ Editor::set_grid_to (GridType gt)
        }
 
        /* show appropriate rulers for this grid setting.
-        * TODO: perhaps make this optional.
-        * Currently this is 'required' because the RULER calculates the grid_marks which will be used by grid_lines
         */
        if (grid_musical()) {
                ruler_tempo_action->set_active(true);
                ruler_meter_action->set_active(true);
-
                ruler_bbt_action->set_active(true);
-               ruler_timecode_action->set_active(false);
-               ruler_minsec_action->set_active(false);
-               ruler_samples_action->set_active(false);
-       } else if (_grid_type == GridTypeSmpte) {
-               ruler_tempo_action->set_active(false);
-               ruler_meter_action->set_active(false);
-
-               ruler_bbt_action->set_active(false);
+
+               if ( UIConfiguration::instance().get_rulers_follow_grid() ) {
+                       ruler_timecode_action->set_active(false);
+                       ruler_minsec_action->set_active(false);
+                       ruler_samples_action->set_active(false);
+               }
+       } else if (_grid_type == GridTypeTimecode) {
                ruler_timecode_action->set_active(true);
-               ruler_minsec_action->set_active(false);
-               ruler_samples_action->set_active(false);
+
+               if ( UIConfiguration::instance().get_rulers_follow_grid() ) {
+                       ruler_tempo_action->set_active(false);
+                       ruler_meter_action->set_active(false);
+                       ruler_bbt_action->set_active(false);
+                       ruler_minsec_action->set_active(false);
+                       ruler_samples_action->set_active(false);
+               }
        } else if (_grid_type == GridTypeMinSec) {
-               ruler_tempo_action->set_active(false);
-               ruler_meter_action->set_active(false);
+               ruler_minsec_action->set_active(true);
 
-               ruler_bbt_action->set_active(false);
-               ruler_timecode_action->set_active(false);
+               if ( UIConfiguration::instance().get_rulers_follow_grid() ) {
+                       ruler_tempo_action->set_active(false);
+                       ruler_meter_action->set_active(false);
+                       ruler_bbt_action->set_active(false);
+                       ruler_timecode_action->set_active(false);
+                       ruler_samples_action->set_active(false);
+               }
+       } else if (_grid_type == GridTypeCDFrame) {
+               ruler_cd_marker_action->set_active(true);
                ruler_minsec_action->set_active(true);
-               ruler_samples_action->set_active(false);
-       } else if (_grid_type == GridTypeSamples) {
-               ruler_tempo_action->set_active(false);
-               ruler_meter_action->set_active(false);
 
-               ruler_bbt_action->set_active(false);
-               ruler_timecode_action->set_active(false);
-               ruler_minsec_action->set_active(false);
-               ruler_samples_action->set_active(true);
+               if ( UIConfiguration::instance().get_rulers_follow_grid() ) {
+                       ruler_tempo_action->set_active(false);
+                       ruler_meter_action->set_active(false);
+                       ruler_bbt_action->set_active(false);
+                       ruler_timecode_action->set_active(false);
+                       ruler_samples_action->set_active(false);
+               }
        }
 
        instant_save ();
@@ -2827,7 +2835,7 @@ Editor::snap_to_internal (MusicSample& start, RoundMode direction, SnapPref pref
        samplepos_t best = max_samplepos; // this records the best snap-result we've found so far
 
        /* check snap-to-marker */
-       if (UIConfiguration::instance().get_snap_to_marks()) {
+       if ( (pref == SnapToAny) && UIConfiguration::instance().get_snap_to_marks()) {
                if (for_mark) {
                        return;
                }
@@ -2837,31 +2845,31 @@ Editor::snap_to_internal (MusicSample& start, RoundMode direction, SnapPref pref
        }
 
        /* check snap-to-region-{start/end/sync} */
-       if (UIConfiguration::instance().get_snap_to_region_start() || UIConfiguration::instance().get_snap_to_region_end() || UIConfiguration::instance().get_snap_to_region_sync()) {
+       if (
+               (pref == SnapToAny) &&
+               (UIConfiguration::instance().get_snap_to_region_start() || UIConfiguration::instance().get_snap_to_region_end() || UIConfiguration::instance().get_snap_to_region_sync())
+               ) {
                if (!region_boundary_cache.empty()) {
 
-                       vector<samplepos_t>::iterator prev = region_boundary_cache.end ();
-                       vector<samplepos_t>::iterator next = region_boundary_cache.end ();
-
-                       if (direction > 0) {
-                               next = std::upper_bound (region_boundary_cache.begin(), region_boundary_cache.end(), presnap);
-                       } else {
-                               next = std::lower_bound (region_boundary_cache.begin(), region_boundary_cache.end(), presnap);
-                       }
-
+                       vector<samplepos_t>::iterator prev = region_boundary_cache.begin();
+                       vector<samplepos_t>::iterator next = std::upper_bound (region_boundary_cache.begin(), region_boundary_cache.end(), presnap);
                        if (next != region_boundary_cache.begin ()) {
                                prev = next;
                                prev--;
                        }
 
-                       samplepos_t const p = (prev == region_boundary_cache.end()) ? region_boundary_cache.front () : *prev;
-                       samplepos_t const n = (next == region_boundary_cache.end()) ? region_boundary_cache.back () : *next;
-
-                       if (presnap > (p + n) / 2) {
-                               test = n;
-                       } else {
-                               test = p;
+                       if ((direction == RoundUpMaybe || direction == RoundUpAlways))
+                               test = *next;
+                       else if ((direction == RoundDownMaybe || direction == RoundDownAlways))
+                               test = *prev;
+                       else if (direction ==  0) {
+                               if ((presnap - *prev) < (*next - presnap)) {
+                                       test = *prev;
+                               } else {
+                                       test = *next;
+                               }
                        }
+
                }
 
                check_best_snap(presnap, test, dist, best);
@@ -2869,11 +2877,6 @@ Editor::snap_to_internal (MusicSample& start, RoundMode direction, SnapPref pref
 
        /* check Grid */
        if (UIConfiguration::instance().get_snap_to_grid() && (_grid_type != GridTypeNone)) {
-
-               /* if SnapToGrid is selected, the user wants to prioritize the music grid
-                * in this case we should reset the best distance, so Grid will prevail */
-               dist = max_samplepos;
-
                test = snap_to_grid (grid_marks, presnap, direction);
                check_best_snap(presnap, test, dist, best);
        }
@@ -3197,11 +3200,9 @@ Editor::build_grid_type_menu ()
        grid_type_selector.AddMenuElem (Menu_Helpers::MenuElem (_("Septuplets"), *_septuplet_menu));
 
        grid_type_selector.AddMenuElem(SeparatorElem());
-       grid_type_selector.AddMenuElem (MenuElem (grid_type_strings[(int)GridTypeSmpte], sigc::bind (sigc::mem_fun(*this, &Editor::grid_type_selection_done), (GridType) GridTypeSmpte)));
+       grid_type_selector.AddMenuElem (MenuElem (grid_type_strings[(int)GridTypeTimecode], sigc::bind (sigc::mem_fun(*this, &Editor::grid_type_selection_done), (GridType) GridTypeTimecode)));
        grid_type_selector.AddMenuElem (MenuElem (grid_type_strings[(int)GridTypeMinSec], sigc::bind (sigc::mem_fun(*this, &Editor::grid_type_selection_done), (GridType) GridTypeMinSec)));
-       grid_type_selector.AddMenuElem (MenuElem (grid_type_strings[(int)GridTypeSamples], sigc::bind (sigc::mem_fun(*this, &Editor::grid_type_selection_done), (GridType) GridTypeSamples)));
-
-       set_size_request_to_display_given_text (grid_type_selector, _("Long Grid"), COMBO_TRIANGLE_WIDTH, 2); // problem: some of the rarely-used grid names are very long.  Just do something arbitary, translators: rename this if needed
+       grid_type_selector.AddMenuElem (MenuElem (grid_type_strings[(int)GridTypeCDFrame], sigc::bind (sigc::mem_fun(*this, &Editor::grid_type_selection_done), (GridType) GridTypeCDFrame)));
 }
 
 void
@@ -3990,9 +3991,9 @@ Editor::get_grid_beat_divisions(samplepos_t position)
        case GridTypeBeatDiv2:   return 2;
 
        case GridTypeNone:       return 0;
-       case GridTypeSmpte:      return 0;
+       case GridTypeTimecode:   return 0;
        case GridTypeMinSec:     return 0;
-       case GridTypeSamples:    return 0;
+       case GridTypeCDFrame:    return 0;
        default:                 return 0;
        }
        return 0;
@@ -4034,9 +4035,9 @@ Editor::get_grid_music_divisions (uint32_t event_state)
        case GridTypeBar :       return -1;
 
        case GridTypeNone:       return 0;
-       case GridTypeSmpte:      return 0;
+       case GridTypeTimecode:   return 0;
        case GridTypeMinSec:     return 0;
-       case GridTypeSamples:    return 0;
+       case GridTypeCDFrame:    return 0;
        }
        return 0;
 }
@@ -4677,8 +4678,9 @@ Editor::get_preferred_edit_position (EditIgnoreOption ignore, bool from_context_
 
        switch (ep) {
        case EditAtPlayhead:
-               if (_dragging_playhead && _control_scroll_target) {
-                       where = *_control_scroll_target;
+               if (_dragging_playhead) {
+                       /* NOTE: since the user is dragging with the mouse, this operation will implicitly be Snapped */
+                       where = playhead_cursor->current_sample();
                } else {
                        where = _session->audible_sample();
                }
@@ -5795,9 +5797,7 @@ Editor::super_rapid_screen_update ()
        if (!UIConfiguration::instance().get_show_snapped_cursor()) {
                snapped_cursor->hide ();
        } else if (_edit_point == EditAtPlayhead && !_dragging_playhead) {
-               snap_to (where);  // can't use snap_to_with_modifier?
-               snapped_cursor->set_position (where.sample);
-               snapped_cursor->show ();
+               /* EditAtPlayhead does not snap */
        } else if (_edit_point == EditAtSelectedMarker) {
                /* NOTE: I don't think EditAtSelectedMarker should snap. They are what they are.
                 * however, the current editing code -does- snap so I'll draw it that way for now.
@@ -6169,6 +6169,11 @@ Editor::ui_parameter_changed (string parameter)
                if (_verbose_cursor) {
                        playhead_cursor->set_sensitive (UIConfiguration::instance().get_draggable_playhead());
                }
+       } else if (parameter == "use-note-bars-for-velocity") {
+               ArdourCanvas::Note::set_show_velocity_bars (UIConfiguration::instance().get_use_note_bars_for_velocity());
+               _track_canvas->request_redraw (_track_canvas->visible_area());
+       } else if (parameter == "use-note-color-for-velocity") {
+               /* handled individually by each MidiRegionView */
        }
 }