generalize VCA assign/unassign code.
[ardour.git] / gtk2_ardour / editor.cc
index 49b5b5491e49b51128696b6ab4cc4ab0a47f5d8f..345694d1015de02cb12811ee1f3c4fb9fbb23af5 100644 (file)
@@ -212,8 +212,8 @@ static const gchar *_zoom_focus_strings[] = {
        N_("Right"),
        N_("Center"),
        N_("Playhead"),
-       N_("Mouse"),
-       N_("Edit point"),
+       N_("Mouse"),
+       N_("Edit point"),
        0
 };
 
@@ -391,7 +391,8 @@ Editor::Editor ()
        , tempo_lines (0)
        , global_rect_group (0)
        , time_line_group (0)
-       , tempo_or_meter_marker_menu (0)
+       , tempo_marker_menu (0)
+       , meter_marker_menu (0)
        , marker_menu (0)
        , range_marker_menu (0)
        , transport_marker_menu (0)
@@ -436,6 +437,7 @@ Editor::Editor ()
        , show_gain_after_trim (false)
        , selection_op_cmd_depth (0)
        , selection_op_history_it (0)
+       , no_save_instant (false)
        , current_timefx (0)
        , current_mixer_strip (0)
        , show_editor_mixer_when_tracks_arrive (false)
@@ -507,6 +509,7 @@ Editor::Editor ()
 
        TimeAxisView::setup_sizes ();
        ArdourMarker::setup_sizes (timebar_height);
+       TempoCurve::setup_sizes (timebar_height);
 
        bbt_label.set_name ("EditorRulerLabel");
        bbt_label.set_size_request (-1, (int)timebar_height);
@@ -949,7 +952,7 @@ Editor::set_entered_track (TimeAxisView* tav)
 void
 Editor::instant_save ()
 {
-       if (!constructed || !ARDOUR_UI::instance()->session_loaded) {
+       if (!constructed || !ARDOUR_UI::instance()->session_loaded || no_save_instant) {
                return;
        }
 
@@ -1364,6 +1367,7 @@ Editor::set_session (Session *t)
        _session->RouteAdded.connect (_session_connections, invalidator (*this), boost::bind (&Editor::add_routes, this, _1), gui_context());
        _session->DirtyChanged.connect (_session_connections, invalidator (*this), boost::bind (&Editor::update_title, this), gui_context());
        _session->tempo_map().PropertyChanged.connect (_session_connections, invalidator (*this), boost::bind (&Editor::tempo_map_changed, this, _1), gui_context());
+       _session->tempo_map().MetricPositionChanged.connect (_session_connections, invalidator (*this), boost::bind (&Editor::marker_position_changed, this), gui_context());
        _session->Located.connect (_session_connections, invalidator (*this), boost::bind (&Editor::located, this), gui_context());
        _session->config.ParameterChanged.connect (_session_connections, invalidator (*this), boost::bind (&Editor::parameter_changed, this, _1), gui_context());
        _session->StateSaved.connect (_session_connections, invalidator (*this), boost::bind (&Editor::session_state_saved, this, _1), gui_context());
@@ -1669,7 +1673,7 @@ Editor::build_track_context_menu ()
 {
        using namespace Menu_Helpers;
 
-       MenuList& edit_items = track_context_menu.items();
+       MenuList& edit_items = track_context_menu.items();
        edit_items.clear();
 
        add_dstream_context_items (edit_items);
@@ -1681,7 +1685,7 @@ Editor::build_track_bus_context_menu ()
 {
        using namespace Menu_Helpers;
 
-       MenuList& edit_items = track_context_menu.items();
+       MenuList& edit_items = track_context_menu.items();
        edit_items.clear();
 
        add_bus_context_items (edit_items);
@@ -2134,6 +2138,37 @@ Editor::snap_type() const
        return _snap_type;
 }
 
+bool
+Editor::snap_musical() const
+{
+       switch (_snap_type) {
+       case SnapToBeatDiv128:
+       case SnapToBeatDiv64:
+       case SnapToBeatDiv32:
+       case SnapToBeatDiv28:
+       case SnapToBeatDiv24:
+       case SnapToBeatDiv20:
+       case SnapToBeatDiv16:
+       case SnapToBeatDiv14:
+       case SnapToBeatDiv12:
+       case SnapToBeatDiv10:
+       case SnapToBeatDiv8:
+       case SnapToBeatDiv7:
+       case SnapToBeatDiv6:
+       case SnapToBeatDiv5:
+       case SnapToBeatDiv4:
+       case SnapToBeatDiv3:
+       case SnapToBeatDiv2:
+       case SnapToBeat:
+       case SnapToBar:
+               return true;
+       default:
+               break;
+       }
+
+       return false;
+}
+
 SnapMode
 Editor::snap_mode() const
 {
@@ -2184,14 +2219,10 @@ Editor::set_snap_to (SnapType st)
        case SnapToBeatDiv4:
        case SnapToBeatDiv3:
        case SnapToBeatDiv2: {
-               ARDOUR::TempoMap::BBTPointList::const_iterator current_bbt_points_begin;
-               ARDOUR::TempoMap::BBTPointList::const_iterator current_bbt_points_end;
-
-               compute_current_bbt_points (leftmost_frame, leftmost_frame + current_page_samples(),
-                                           current_bbt_points_begin, current_bbt_points_end);
-               compute_bbt_ruler_scale (leftmost_frame, leftmost_frame + current_page_samples(),
-                                        current_bbt_points_begin, current_bbt_points_end);
-               update_tempo_based_rulers (current_bbt_points_begin, current_bbt_points_end);
+               std::vector<TempoMap::BBTPoint> grid;
+               compute_current_bbt_points (grid, leftmost_frame, leftmost_frame + current_page_samples());
+               compute_bbt_ruler_scale (grid, leftmost_frame, leftmost_frame + current_page_samples());
+               update_tempo_based_rulers (grid);
                break;
        }
 
@@ -2289,6 +2320,7 @@ Editor::set_state (const XMLNode& node, int version)
 {
        XMLProperty const * prop;
        set_id (node);
+       PBD::Unwinder<bool> nsi (no_save_instant, true);
 
        Tabbable::set_state (node, version);
 
@@ -2327,10 +2359,16 @@ Editor::set_state (const XMLNode& node, int version)
 
        if ((prop = node.property ("snap-to"))) {
                snap_type_selection_done ((SnapType) string_2_enum (prop->value(), _snap_type));
+               set_snap_to ((SnapType) string_2_enum (prop->value(), _snap_type));
        }
 
        if ((prop = node.property ("snap-mode"))) {
                snap_mode_selection_done((SnapMode) string_2_enum (prop->value(), _snap_mode));
+               /* set text of Dropdown. in case _snap_mode == SnapOff (default)
+                * snap_mode_selection_done() will only mark an already active item as active
+                * which does not trigger set_text().
+                */
+               set_snap_mode ((SnapMode) string_2_enum (prop->value(), _snap_mode));
        }
 
        if ((prop = node.property ("internal-snap-to"))) {
@@ -2523,10 +2561,10 @@ Editor::get_state ()
 
        node->add_child_nocopy (Tabbable::get_state());
 
-       snprintf(buf,sizeof(buf), "%d",gtk_paned_get_position (static_cast<Paned*>(&edit_pane)->gobj()));
+       snprintf(buf,sizeof(buf), "%f", paned_position_as_fraction (edit_pane, false));
        node->add_property("edit-horizontal-pane-pos", string(buf));
        node->add_property("notebook-shrunk", _notebook_shrunk ? "1" : "0");
-       snprintf(buf,sizeof(buf), "%d",gtk_paned_get_position (static_cast<Paned*>(&editor_summary_pane)->gobj()));
+       snprintf(buf,sizeof(buf), "%f", paned_position_as_fraction (editor_summary_pane, true));
        node->add_property("edit-vertical-pane-pos", string(buf));
 
        maybe_add_mixer_strip_width (*node);
@@ -3870,12 +3908,13 @@ Editor::pane_allocation_handler (Allocation &alloc, Paned* which)
 {
        /* recover or initialize pane positions. do this here rather than earlier because
           we don't want the positions to change the child allocations, which they seem to do.
+
+          See comments in mixer_ui.cc about how this works.
         */
 
-       int pos;
-       XMLProperty const * prop;
-       char buf[32];
-       XMLNode* node = ARDOUR_UI::instance()->editor_settings();
+       float pos;
+       XMLProperty* prop;
+       XMLNode* geometry = ARDOUR_UI::instance()->editor_settings();
 
        enum Pane {
                Horizontal = 0x1,
@@ -3884,8 +3923,6 @@ Editor::pane_allocation_handler (Allocation &alloc, Paned* which)
 
        static Pane done;
 
-       XMLNode* geometry = find_named_node (*node, "geometry");
-
        if (which == static_cast<Paned*> (&edit_pane)) {
 
                if (done & Horizontal) {
@@ -3899,17 +3936,23 @@ Editor::pane_allocation_handler (Allocation &alloc, Paned* which)
                if (!geometry || (prop = geometry->property ("edit-horizontal-pane-pos")) == 0) {
                        /* initial allocation is 90% to canvas, 10% to notebook */
                        pos = (int) floor (alloc.get_width() * 0.90f);
-                       snprintf (buf, sizeof(buf), "%d", pos);
                } else {
-                       pos = atoi (prop->value());
+                       pos = atof (prop->value());
                }
 
-               if (GTK_WIDGET(edit_pane.gobj())->allocation.width > pos) {
-                       edit_pane.set_position (pos);
+               if (pos > 1.0f) {
+                       /* older versions of Ardour stored absolute position */
+                       if (alloc.get_width() > pos) {
+                               edit_pane.set_position (pos);
+                               done = (Pane) (done | Horizontal);
+                       }
+               } else {
+                       if (alloc.get_width() > 1.0/pos) {
+                               paned_set_position_as_fraction (edit_pane, pos, false);
+                               done = (Pane) (done | Horizontal);
+                       }
                }
 
-               done = (Pane) (done | Horizontal);
-
        } else if (which == static_cast<Paned*> (&editor_summary_pane)) {
 
                if (done & Vertical) {
@@ -3919,17 +3962,23 @@ Editor::pane_allocation_handler (Allocation &alloc, Paned* which)
                if (!geometry || (prop = geometry->property ("edit-vertical-pane-pos")) == 0) {
                        /* initial allocation is 90% to canvas, 10% to summary */
                        pos = (int) floor (alloc.get_height() * 0.90f);
-                       snprintf (buf, sizeof(buf), "%d", pos);
                } else {
 
-                       pos = atoi (prop->value());
+                       pos = atof (prop->value());
                }
 
-               if (GTK_WIDGET(editor_summary_pane.gobj())->allocation.height > pos) {
-                       editor_summary_pane.set_position (pos);
+               if (pos > 1.0f) {
+                       /* older versions of Ardour stored absolute position */
+                       if (alloc.get_height() > pos) {
+                               editor_summary_pane.set_position (pos);
+                               done = (Pane) (done | Vertical);
+                       }
+               } else {
+                       if (alloc.get_height() > 1.0/pos) {
+                               paned_set_position_as_fraction (editor_summary_pane, pos, true);
+                               done = (Pane) (done | Vertical);
+                       }
                }
-
-               done = (Pane) (done | Vertical);
        }
 }
 
@@ -3944,11 +3993,9 @@ Editor::set_show_measures (bool yn)
                                tempo_lines->show();
                        }
 
-                       ARDOUR::TempoMap::BBTPointList::const_iterator begin;
-                       ARDOUR::TempoMap::BBTPointList::const_iterator end;
-
-                       compute_current_bbt_points (leftmost_frame, leftmost_frame + current_page_samples(), begin, end);
-                       draw_measures (begin, end);
+                       std::vector<TempoMap::BBTPoint> grid;
+                       compute_current_bbt_points (grid, leftmost_frame, leftmost_frame + current_page_samples());
+                       draw_measures (grid);
                }
 
                instant_save ();
@@ -4069,7 +4116,7 @@ Editor::get_grid_type_as_beats (bool& success, framepos_t position)
                return Evoral::Beats(1.0);
        case SnapToBar:
                if (_session) {
-                       return Evoral::Beats(_session->tempo_map().meter_at (position).divisions_per_bar());
+                       return Evoral::Beats(_session->tempo_map().meter_at_frame (position).divisions_per_bar());
                }
                break;
        default:
@@ -4574,14 +4621,10 @@ Editor::visual_changer (const VisualChange& vc)
 
                compute_fixed_ruler_scale ();
 
-               ARDOUR::TempoMap::BBTPointList::const_iterator current_bbt_points_begin;
-               ARDOUR::TempoMap::BBTPointList::const_iterator current_bbt_points_end;
-
-               compute_current_bbt_points (vc.time_origin, pending_visual_change.time_origin + current_page_samples(),
-                                           current_bbt_points_begin, current_bbt_points_end);
-               compute_bbt_ruler_scale (vc.time_origin, pending_visual_change.time_origin + current_page_samples(),
-                                        current_bbt_points_begin, current_bbt_points_end);
-               update_tempo_based_rulers (current_bbt_points_begin, current_bbt_points_end);
+               std::vector<TempoMap::BBTPoint> grid;
+               compute_current_bbt_points (grid, vc.time_origin, pending_visual_change.time_origin + current_page_samples());
+               compute_bbt_ruler_scale (grid, vc.time_origin, pending_visual_change.time_origin + current_page_samples());
+               update_tempo_based_rulers (grid);
 
                update_video_timeline();
        }
@@ -5740,7 +5783,7 @@ Editor::set_script_action_name (int i, const std::string& n)
        assert (act);
        if (n.empty ()) {
                act->set_label (string_compose (_("Unset #%1"), i + 1));
-               act->set_tooltip (_("(no action bound"));
+               act->set_tooltip (_("no action bound"));
                act->set_sensitive (false);
        } else {
                act->set_label (n);