diff --git a/gtk2_ardour/editing.cc b/gtk2_ardour/editing.cc index 86d50fcda5..2c8e69e219 100644 --- a/gtk2_ardour/editing.cc +++ b/gtk2_ardour/editing.cc @@ -182,6 +182,14 @@ const char *notenamedisplaystrs[] = { #undef NOTENAMEDISPLAY #define NOTENAMEDISPLAY(a) /*empty*/ +#undef MARKERCLICKBEHAVIOR +#define MARKERCLICKBEHAVIOR(s) N_(#s), +const char *markerclickbehaviorstrs[] = { + #include "editing_syms.h" + 0 +}; +#undef MARKERCLICKBEHAVIOR +#define MARKERCLICKBEHAVIOR(a) /*empty*/ } // namespace Editing diff --git a/gtk2_ardour/editing.h b/gtk2_ardour/editing.h index 11f87ae38d..304eb3af7f 100644 --- a/gtk2_ardour/editing.h +++ b/gtk2_ardour/editing.h @@ -43,6 +43,7 @@ #define INSERTTIMEOPT(a) /*empty*/ #define TEMPOEDITBEHAVIOR(a) /*empty*/ #define NOTENAMEDISPLAY(a) /*empty*/ +#define MARKERCLICKBEHAVIOR(a) /*empty*/ namespace Editing { @@ -211,6 +212,18 @@ inline const char* enum2str(NoteNameDisplay m) {return notenamedisplaystrs[m];} #undef NOTENAMEDISPLAY #define NOTENAMEDISPLAY(a) /*empty*/ +#undef MARKERCLICKBEHAVIOR +#define MARKERCLICKBEHAVIOR(a) a, +enum MarkerClickBehavior { + #include "editing_syms.h" +}; +#undef MARKERCLICKBEHAVIOR +#define MARKERCLICKBEHAVIOR(a) /*empty*/ + +extern const char *markerclickbehaviorstrs[]; +inline const char* enum2str(MarkerClickBehavior m) {return markerclickbehaviorstrs[m];} +MarkerClickBehavior str2markerclickbehavior(const std::string &); + ///////////////////// // These don't need their state saved. yet... enum CutCopyOp { diff --git a/gtk2_ardour/editing_convert.h b/gtk2_ardour/editing_convert.h index 8e4f5f7949..38b9ecba78 100644 --- a/gtk2_ardour/editing_convert.h +++ b/gtk2_ardour/editing_convert.h @@ -33,6 +33,7 @@ DEFINE_ENUM_CONVERT(Editing::EditPoint) DEFINE_ENUM_CONVERT(Editing::RegionListSortType) DEFINE_ENUM_CONVERT(Editing::MouseMode) DEFINE_ENUM_CONVERT(Editing::NoteNameDisplay) +DEFINE_ENUM_CONVERT(Editing::MarkerClickBehavior) } // namespace PBD diff --git a/gtk2_ardour/editing_syms.h b/gtk2_ardour/editing_syms.h index f934f80624..e7977c1964 100644 --- a/gtk2_ardour/editing_syms.h +++ b/gtk2_ardour/editing_syms.h @@ -109,6 +109,10 @@ INSERTTIMEOPT(LeaveIntersected) INSERTTIMEOPT(MoveIntersected) INSERTTIMEOPT(SplitIntersected) +MARKERCLICKBEHAVIOR(MarkerClickSelectOnly) +MARKERCLICKBEHAVIOR(MarkerClickLocate) +MARKERCLICKBEHAVIOR(MarkerClickLocateWhenStopped) + NOTENAMEDISPLAY(Always) NOTENAMEDISPLAY(WithMIDNAM) NOTENAMEDISPLAY(Never) diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index 61eb7740e6..7c6150f43a 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -267,6 +267,7 @@ Editor::Editor () , pre_internal_snap_mode (SnapOff) , internal_grid_type (GridTypeBeat) , internal_snap_mode (SnapOff) + , marker_click_behavior (MarkerClickSelectOnly) , _join_object_range_state (JOIN_OBJECT_RANGE_NONE) , _notebook_shrunk (false) , entered_marker (0) @@ -2527,6 +2528,9 @@ Editor::set_state (const XMLNode& node, int version) node.get_property ("zoom-focus", zoom_focus); zoom_focus_selection_done (zoom_focus); + node.get_property ("marker-click-behavior", marker_click_behavior); + marker_click_behavior_selection_done (marker_click_behavior); + double z; if (node.get_property ("zoom", z)) { /* older versions of ardour used floating point samples_per_pixel */ @@ -2738,6 +2742,7 @@ Editor::get_state () const node->set_property ("pre-internal-snap-mode", pre_internal_snap_mode); node->set_property ("edit-point", _edit_point); node->set_property ("visible-track-count", _visible_track_count); + node->set_property ("marker-click-behavior", marker_click_behavior); node->set_property ("draw-length", _draw_length); node->set_property ("draw-velocity", _draw_velocity); @@ -4139,6 +4144,15 @@ Editor::zoom_focus_selection_done (ZoomFocus f) } } +void +Editor::marker_click_behavior_selection_done (MarkerClickBehavior m) +{ + RefPtr ract = marker_click_behavior_action (m); + if (ract) { + ract->set_active (); + } +} + void Editor::build_track_count_menu () { @@ -4327,6 +4341,31 @@ Editor::cycle_zoom_focus () } } +void +Editor::set_marker_click_behavior (MarkerClickBehavior m) +{ + if (marker_click_behavior != m) { + marker_click_behavior = m; + instant_save (); + } +} + +void +Editor::cycle_marker_click_behavior () +{ + switch (marker_click_behavior) { + case MarkerClickSelectOnly: + set_marker_click_behavior (MarkerClickLocate); + break; + case MarkerClickLocate: + set_marker_click_behavior (MarkerClickLocateWhenStopped); + break; + case MarkerClickLocateWhenStopped: + set_marker_click_behavior (MarkerClickSelectOnly); + break; + } +} + void Editor::update_grid () { diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h index 05586f2f33..f4038f542d 100644 --- a/gtk2_ardour/editor.h +++ b/gtk2_ardour/editor.h @@ -353,6 +353,10 @@ public: void tav_zoom_step (bool coarser); void tav_zoom_smooth (bool coarser, bool force_all); + void cycle_marker_click_behavior (); + void set_marker_click_behavior (Editing::MarkerClickBehavior); + Editing::MarkerClickBehavior get_marker_click_behavior () const { return marker_click_behavior; } + /* stuff that AudioTimeAxisView and related classes use */ void clear_playlist (std::shared_ptr); @@ -685,6 +689,8 @@ private: Editing::SnapMode internal_snap_mode; Editing::MouseMode effective_mouse_mode () const; + Editing::MarkerClickBehavior marker_click_behavior; + enum JoinObjectRangeState { JOIN_OBJECT_RANGE_NONE, /** `join object/range' mode is active and the mouse is over a place where object mode should happen */ @@ -2055,6 +2061,11 @@ private: Glib::RefPtr zoom_focus_action (Editing::ZoomFocus); + /* Marker Click Radio */ + Glib::RefPtr marker_click_behavior_action (Editing::MarkerClickBehavior); + void marker_click_behavior_chosen (Editing::MarkerClickBehavior); + void marker_click_behavior_selection_done (Editing::MarkerClickBehavior); + Gtk::HBox _track_box; Gtk::HBox _zoom_box; diff --git a/gtk2_ardour/editor_actions.cc b/gtk2_ardour/editor_actions.cc index 91b8b1cad0..4d227da24f 100644 --- a/gtk2_ardour/editor_actions.cc +++ b/gtk2_ardour/editor_actions.cc @@ -556,6 +556,14 @@ Editor::register_actions () ActionManager::register_action (editor_actions, X_("cycle-zoom-focus"), _("Next Zoom Focus"), sigc::mem_fun (*this, &Editor::cycle_zoom_focus)); + Glib::RefPtr marker_click_actions = ActionManager::create_action_group (bindings, X_("MarkerClickBehavior")); + RadioAction::Group marker_click_group; + + radio_reg_sens (marker_click_actions, marker_click_group, "marker-click-select-only", _("Marker Click Only Selects"), sigc::bind (sigc::mem_fun(*this, &Editor::marker_click_behavior_chosen), Editing::MarkerClickSelectOnly)); + radio_reg_sens (marker_click_actions, marker_click_group, "marker-click-locate", _("Locate to Marker on Click"), sigc::bind (sigc::mem_fun(*this, &Editor::marker_click_behavior_chosen), Editing::MarkerClickLocate)); + radio_reg_sens (marker_click_actions, marker_click_group, "marker-click-locate-when-stopped", _("Locate To Marker When Transport Is Not Rolling "), sigc::bind (sigc::mem_fun(*this, &Editor::marker_click_behavior_chosen), Editing::MarkerClickLocateWhenStopped)); + ActionManager::register_action (editor_actions, X_("cycle-marker-click-behavior"), _("Next Marker Click Mode"), sigc::mem_fun (*this, &Editor::cycle_marker_click_behavior)); + Glib::RefPtr lua_script_actions = ActionManager::create_action_group (bindings, X_("LuaAction")); for (int i = 1; i <= MAX_LUA_ACTION_SCRIPTS; ++i) { @@ -1638,6 +1646,26 @@ Editor::edit_point_chosen (EditPoint ep) } } +RefPtr +Editor::marker_click_behavior_action (MarkerClickBehavior m) +{ + const char* action = 0; + RefPtr act; + + switch (m) { + case MarkerClickSelectOnly: + action = X_("marker-click-select-only"); + break; + case MarkerClickLocate: + action = X_("marker-click-locate"); + break; + case MarkerClickLocateWhenStopped: + action = X_("marker-click-locate-when-stopped"); + break; + } + + return ActionManager::get_radio_action (X_("MarkerClickBehavior"), action); +} RefPtr Editor::zoom_focus_action (ZoomFocus focus) @@ -1697,6 +1725,15 @@ Editor::zoom_focus_chosen (ZoomFocus focus) } } +void +Editor::marker_click_behavior_chosen (Editing::MarkerClickBehavior m) +{ + RefPtr ract = marker_click_behavior_action (m); + if (ract && ract->get_active()) { + set_marker_click_behavior (m); + } +} + /** A Configuration parameter has changed. * @param parameter_name Name of the changed parameter. */ diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc index 64817d28da..7e16e17eba 100644 --- a/gtk2_ardour/editor_drag.cc +++ b/gtk2_ardour/editor_drag.cc @@ -4645,7 +4645,19 @@ MarkerDrag::finished (GdkEvent* event, bool movement_occurred) _editor->commit_reversible_selection_op (); } - if (!_editor->session()->config.get_external_sync () && (_editor->edit_point() != Editing::EditAtSelectedMarker)) { + bool do_locate; + switch (_editor->get_marker_click_behavior ()) { + case MarkerClickSelectOnly: + do_locate = false; + break; + case MarkerClickLocate: + do_locate = true; + break; + case MarkerClickLocateWhenStopped: + do_locate = !_editor->session()->transport_state_rolling (); + } + + if (do_locate && !_editor->session()->config.get_external_sync () && (_editor->edit_point() != Editing::EditAtSelectedMarker)) { bool is_start; Location* location = _editor->find_location_from_marker (_marker, is_start); if (location) { diff --git a/gtk2_ardour/enums.cc b/gtk2_ardour/enums.cc index d89327903e..c484414f14 100644 --- a/gtk2_ardour/enums.cc +++ b/gtk2_ardour/enums.cc @@ -61,6 +61,7 @@ setup_gtk_ardour_enums () Gtk::ResponseType dialog_response; AddRouteDialog::TypeWanted type_wanted; NoteNameDisplay note_name_display; + MarkerClickBehavior marker_click_behavior; #define REGISTER(e) enum_writer.register_distinct (typeid(e).name(), i, s); i.clear(); s.clear() #define REGISTER_BITS(e) enum_writer.register_bits (typeid(e).name(), i, s); i.clear(); s.clear() @@ -234,6 +235,10 @@ setup_gtk_ardour_enums () REGISTER_CLASS_ENUM (AddRouteDialog, FoldbackBus); REGISTER (type_wanted); + REGISTER_CLASS_ENUM (Editing, MarkerClickSelectOnly); + REGISTER_CLASS_ENUM (Editing, MarkerClickLocate); + REGISTER_CLASS_ENUM (Editing, MarkerClickLocateWhenStopped); + REGISTER (marker_click_behavior); REGISTER_CLASS_ENUM (Editing, Always); REGISTER_CLASS_ENUM (Editing, WithMIDNAM);