zoom focus and snap mode get the stateful-action treatment

This commit is contained in:
Paul Davis 2025-07-30 15:28:41 -06:00
parent 298df2029b
commit 9c890f2690
12 changed files with 204 additions and 271 deletions

View file

@ -109,14 +109,17 @@ AudioClipEditor::AudioClipEditor (std::string const & name, bool with_transport)
, scroll_fraction (0) , scroll_fraction (0)
, current_line_drag (0) , current_line_drag (0)
{ {
build_upper_toolbar ();
build_canvas ();
build_lower_toolbar ();
load_bindings (); load_bindings ();
register_actions (); register_actions ();
build_canvas ();
build_grid_type_menu (); build_grid_type_menu ();
build_upper_toolbar ();
build_lower_toolbar ();
set_action_defaults ();
} }
void void

View file

@ -61,7 +61,6 @@ CueEditor::CueEditor (std::string const & name, bool with_transport)
horizontal_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &CueEditor::scrolled)); horizontal_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &CueEditor::scrolled));
_history.Changed.connect (history_connection, invalidator (*this), std::bind (&CueEditor::history_changed, this), gui_context()); _history.Changed.connect (history_connection, invalidator (*this), std::bind (&CueEditor::history_changed, this), gui_context());
set_zoom_focus (Editing::ZoomFocusLeft);
} }
CueEditor::~CueEditor () CueEditor::~CueEditor ()
@ -203,16 +202,7 @@ CueEditor::set_zoom_focus (Editing::ZoomFocus zf)
return; return;
} }
std::string str = zoom_focus_strings[(int)zf]; zoom_focus_actions[zf]->set_active (true);
if (str != zoom_focus_selector.get_text()) {
zoom_focus_selector.set_text (str);
}
if (_zoom_focus != zf) {
_zoom_focus = zf;
ZoomFocusChanged (); /* EMIT SIGNAL */
}
} }
void void
@ -415,7 +405,7 @@ CueEditor::build_upper_toolbar ()
_toolbar_outer->pack_start (*_toolbar_inner, true, false); _toolbar_outer->pack_start (*_toolbar_inner, true, false);
build_zoom_focus_menu (); build_zoom_focus_menu ();
zoom_focus_selector.set_text (zoom_focus_strings[(int)_zoom_focus]); zoom_focus_selector.set_text (zoom_focus_strings[(int)zoom_focus()]);
_toolbar_left->pack_start (zoom_in_button, false, false); _toolbar_left->pack_start (zoom_in_button, false, false);
_toolbar_left->pack_start (zoom_out_button, false, false); _toolbar_left->pack_start (zoom_out_button, false, false);
@ -436,10 +426,10 @@ CueEditor::build_zoom_focus_menu ()
using namespace Gtk::Menu_Helpers; using namespace Gtk::Menu_Helpers;
using namespace Editing; using namespace Editing;
zoom_focus_selector.add_menu_elem (MenuElem (zoom_focus_strings[(int)ZoomFocusLeft], sigc::bind (sigc::mem_fun(*this, &EditingContext::zoom_focus_selection_done), (ZoomFocus) ZoomFocusLeft))); zoom_focus_selector.append (zoom_focus_actions[ZoomFocusLeft]);
zoom_focus_selector.add_menu_elem (MenuElem (zoom_focus_strings[(int)ZoomFocusRight], sigc::bind (sigc::mem_fun(*this, &EditingContext::zoom_focus_selection_done), (ZoomFocus) ZoomFocusRight))); zoom_focus_selector.append (zoom_focus_actions[ZoomFocusRight]);
zoom_focus_selector.add_menu_elem (MenuElem (zoom_focus_strings[(int)ZoomFocusCenter], sigc::bind (sigc::mem_fun(*this, &EditingContext::zoom_focus_selection_done), (ZoomFocus) ZoomFocusCenter))); zoom_focus_selector.append (zoom_focus_actions[ZoomFocusCenter]);
zoom_focus_selector.add_menu_elem (MenuElem (zoom_focus_strings[(int)ZoomFocusMouse], sigc::bind (sigc::mem_fun(*this, &EditingContext::zoom_focus_selection_done), (ZoomFocus) ZoomFocusMouse))); zoom_focus_selector.append (zoom_focus_actions[ZoomFocusMouse]);
zoom_focus_selector.set_sizing_texts (zoom_focus_strings); zoom_focus_selector.set_sizing_texts (zoom_focus_strings);
} }
@ -968,12 +958,6 @@ CueEditor::catch_pending_show_region ()
} }
} }
Editing::MouseMode
CueEditor::current_mouse_mode () const
{
return mouse_mode;
}
RegionSelection RegionSelection
CueEditor::region_selection() CueEditor::region_selection()
{ {
@ -983,12 +967,9 @@ CueEditor::region_selection()
} }
void void
CueEditor::mouse_mode_toggled (Editing::MouseMode m) CueEditor::mouse_mode_chosen (Editing::MouseMode m)
{ {
Glib::RefPtr<Gtk::Action> act = get_mouse_mode_action (m); if (!mouse_mode_actions[m]->get_active()) {
Glib::RefPtr<Gtk::ToggleAction> tact = Glib::RefPtr<Gtk::ToggleAction>::cast_dynamic (act);
if (!tact->get_active()) {
/* this was just the notification that the old mode has been /* this was just the notification that the old mode has been
* left. we'll get called again with the new mode active in a * left. we'll get called again with the new mode active in a
* jiffy. * jiffy.
@ -996,8 +977,6 @@ CueEditor::mouse_mode_toggled (Editing::MouseMode m)
return; return;
} }
mouse_mode = m;
/* this should generate a new enter event which will /* this should generate a new enter event which will
trigger the appropriate cursor. trigger the appropriate cursor.
*/ */

View file

@ -101,13 +101,9 @@ class CueEditor : public EditingContext, public PBD::HistoryOwner
* @param next true to move to the next, otherwise move to the previous * @param next true to move to the next, otherwise move to the previous
*/ */
void step_mouse_mode (bool next); void step_mouse_mode (bool next);
/** @return The current mouse mode (gain, object, range, timefx etc.)
* (defined in editing_syms.inc.h)
*/
Editing::MouseMode current_mouse_mode () const;
/** cue editors are *always* used for internal editing */ /** cue editors are *always* used for internal editing */
bool internal_editing() const { return true; } bool internal_editing() const { return true; }
void mouse_mode_toggled (Editing::MouseMode); void mouse_mode_chosen (Editing::MouseMode);
Gdk::Cursor* get_canvas_cursor () const; Gdk::Cursor* get_canvas_cursor () const;
MouseCursors const* cursors () const { MouseCursors const* cursors () const {

View file

@ -131,7 +131,6 @@ EditingContext::EditingContext (std::string const & name)
, _selection_memento (new SelectionMemento()) , _selection_memento (new SelectionMemento())
, _verbose_cursor (nullptr) , _verbose_cursor (nullptr)
, samples_per_pixel (2048) , samples_per_pixel (2048)
, _zoom_focus (ZoomFocusPlayhead)
, bbt_ruler_scale (bbt_show_many) , bbt_ruler_scale (bbt_show_many)
, bbt_bars (0) , bbt_bars (0)
, bbt_bar_helper_on (0) , bbt_bar_helper_on (0)
@ -142,7 +141,6 @@ EditingContext::EditingContext (std::string const & name)
, vertical_adjustment (0.0, 0.0, 10.0, 400.0) , vertical_adjustment (0.0, 0.0, 10.0, 400.0)
, horizontal_adjustment (0.0, 0.0, 1e16) , horizontal_adjustment (0.0, 0.0, 1e16)
, own_bindings (nullptr) , own_bindings (nullptr)
, mouse_mode (MouseObject)
, visual_change_queued (false) , visual_change_queued (false)
, autoscroll_horizontal_allowed (false) , autoscroll_horizontal_allowed (false)
, autoscroll_vertical_allowed (false) , autoscroll_vertical_allowed (false)
@ -329,6 +327,34 @@ EditingContext::disable_automation_bindings ()
} }
} }
void
EditingContext::set_action_defaults ()
{
#ifndef LIVETRAX
follow_playhead_action->set_active (true);
#else
follow_playhead_action->set_active (false);
#endif
mouse_mode_actions[Editing::MouseObject]->set_active (true);
zoom_focus_actions[Editing::ZoomFocusLeft]->set_active (true);
if (snap_mode_actions[Editing::SnapMagnetic]) {
snap_mode_actions[Editing::SnapMagnetic]->set_active (true);
}
if (grid_actions[Editing::GridTypeBeat]) {
grid_actions[Editing::GridTypeBeat]->set_active (true);
}
if (draw_length_actions[DRAW_LEN_AUTO]) {
draw_length_actions[DRAW_LEN_AUTO]->set_active (true);
}
if (draw_velocity_actions[DRAW_VEL_AUTO]) {
draw_velocity_actions[DRAW_VEL_AUTO]->set_active (true);
}
if (draw_channel_actions[DRAW_CHAN_AUTO]) {
draw_channel_actions[DRAW_CHAN_AUTO]->set_active (true);
}
}
void void
EditingContext::register_common_actions (Bindings* common_bindings, std::string const & prefix) EditingContext::register_common_actions (Bindings* common_bindings, std::string const & prefix)
{ {
@ -337,7 +363,10 @@ EditingContext::register_common_actions (Bindings* common_bindings, std::string
reg_sens (_common_actions, "temporal-zoom-out", _("Zoom Out"), sigc::bind (sigc::mem_fun (*this, &EditingContext::temporal_zoom_step), true)); reg_sens (_common_actions, "temporal-zoom-out", _("Zoom Out"), sigc::bind (sigc::mem_fun (*this, &EditingContext::temporal_zoom_step), true));
reg_sens (_common_actions, "temporal-zoom-in", _("Zoom In"), sigc::bind (sigc::mem_fun (*this, &EditingContext::temporal_zoom_step), false)); reg_sens (_common_actions, "temporal-zoom-in", _("Zoom In"), sigc::bind (sigc::mem_fun (*this, &EditingContext::temporal_zoom_step), false));
follow_playhead_action = toggle_reg_sens (_common_actions, "toggle-follow-playhead", _("Follow Playhead"), (sigc::mem_fun(*this, &EditingContext::toggle_follow_playhead))); /* toggle action that represents state */
follow_playhead_action = toggle_reg_sens (_common_actions, "follow-playhead", _("Follow Playhead"), sigc::mem_fun (*this, &EditingContext::follow_playhead_chosen));
/* invokable action that toggles the stateful action */
reg_sens (_common_actions, "toggle-follow-playhead", _("Follow Playhead"), sigc::mem_fun (*this, &EditingContext::toggle_follow_playhead));
undo_action = reg_sens (_common_actions, "undo", S_("Command|Undo"), sigc::bind (sigc::mem_fun (*this, &EditingContext::undo), 1U)); undo_action = reg_sens (_common_actions, "undo", S_("Command|Undo"), sigc::bind (sigc::mem_fun (*this, &EditingContext::undo), 1U));
redo_action = reg_sens (_common_actions, "redo", _("Redo"), sigc::bind (sigc::mem_fun (*this, &EditingContext::redo), 1U)); redo_action = reg_sens (_common_actions, "redo", _("Redo"), sigc::bind (sigc::mem_fun (*this, &EditingContext::redo), 1U));
@ -353,23 +382,23 @@ EditingContext::register_common_actions (Bindings* common_bindings, std::string
RadioAction::Group mouse_mode_group; RadioAction::Group mouse_mode_group;
ActionManager::register_radio_action (_common_actions, mouse_mode_group, "set-mouse-mode-object", _("Grab (Object Tool)"), sigc::bind (sigc::mem_fun (*this, &EditingContext::mouse_mode_toggled), Editing::MouseObject)); mouse_mode_actions[Editing::MouseObject] = ActionManager::register_radio_action (_common_actions, mouse_mode_group, "set-mouse-mode-object", _("Grab (Object Tool)"), sigc::bind (sigc::mem_fun (*this, &EditingContext::mouse_mode_chosen), Editing::MouseObject));
ActionManager::register_radio_action (_common_actions, mouse_mode_group, "set-mouse-mode-range", _("Range Tool"), sigc::bind (sigc::mem_fun (*this, &EditingContext::mouse_mode_toggled), Editing::MouseRange)); mouse_mode_actions[Editing::MouseRange] = ActionManager::register_radio_action (_common_actions, mouse_mode_group, "set-mouse-mode-range", _("Range Tool"), sigc::bind (sigc::mem_fun (*this, &EditingContext::mouse_mode_chosen), Editing::MouseRange));
ActionManager::register_radio_action (_common_actions, mouse_mode_group, "set-mouse-mode-draw", _("Note Drawing Tool"), sigc::bind (sigc::mem_fun (*this, &EditingContext::mouse_mode_toggled), Editing::MouseDraw)); mouse_mode_actions[Editing::MouseDraw] = ActionManager::register_radio_action (_common_actions, mouse_mode_group, "set-mouse-mode-draw", _("Note Drawing Tool"), sigc::bind (sigc::mem_fun (*this, &EditingContext::mouse_mode_chosen), Editing::MouseDraw));
ActionManager::register_radio_action (_common_actions, mouse_mode_group, "set-mouse-mode-timefx", _("Time FX Tool"), sigc::bind (sigc::mem_fun (*this, &EditingContext::mouse_mode_toggled), Editing::MouseTimeFX)); mouse_mode_actions[Editing::MouseTimeFX] = ActionManager::register_radio_action (_common_actions, mouse_mode_group, "set-mouse-mode-timefx", _("Time FX Tool"), sigc::bind (sigc::mem_fun (*this, &EditingContext::mouse_mode_chosen), Editing::MouseTimeFX));
ActionManager::register_radio_action (_common_actions, mouse_mode_group, "set-mouse-mode-grid", _("Grid Tool"), sigc::bind (sigc::mem_fun (*this, &EditingContext::mouse_mode_toggled), Editing::MouseGrid)); mouse_mode_actions[Editing::MouseGrid] = ActionManager::register_radio_action (_common_actions, mouse_mode_group, "set-mouse-mode-grid", _("Grid Tool"), sigc::bind (sigc::mem_fun (*this, &EditingContext::mouse_mode_chosen), Editing::MouseGrid));
ActionManager::register_radio_action (_common_actions, mouse_mode_group, "set-mouse-mode-content", _("Internal Edit (Content Tool)"), sigc::bind (sigc::mem_fun (*this, &EditingContext::mouse_mode_toggled), Editing::MouseContent)); mouse_mode_actions[Editing::MouseContent] = ActionManager::register_radio_action (_common_actions, mouse_mode_group, "set-mouse-mode-content", _("Internal Edit (Content Tool)"), sigc::bind (sigc::mem_fun (*this, &EditingContext::mouse_mode_chosen), Editing::MouseContent));
ActionManager::register_radio_action (_common_actions, mouse_mode_group, "set-mouse-mode-cut", _("Cut Tool"), sigc::bind (sigc::mem_fun (*this, &EditingContext::mouse_mode_toggled), Editing::MouseCut)); mouse_mode_actions[Editing::MouseCut] = ActionManager::register_radio_action (_common_actions, mouse_mode_group, "set-mouse-mode-cut", _("Cut Tool"), sigc::bind (sigc::mem_fun (*this, &EditingContext::mouse_mode_chosen), Editing::MouseCut));
zoom_actions = ActionManager::create_action_group (common_bindings, prefix + X_("Zoom")); zoom_actions = ActionManager::create_action_group (common_bindings, prefix + X_("Zoom"));
RadioAction::Group zoom_group; RadioAction::Group zoom_group;
radio_reg_sens (zoom_actions, zoom_group, "zoom-focus-left", _("Zoom Focus Left"), sigc::bind (sigc::mem_fun (*this, &EditingContext::zoom_focus_chosen), Editing::ZoomFocusLeft)); zoom_focus_actions[Editing::ZoomFocusLeft] = radio_reg_sens (zoom_actions, zoom_group, "zoom-focus-left", _("Zoom Focus Left"), sigc::bind (sigc::mem_fun (*this, &EditingContext::zoom_focus_chosen), Editing::ZoomFocusLeft));
radio_reg_sens (zoom_actions, zoom_group, "zoom-focus-right", _("Zoom Focus Right"), sigc::bind (sigc::mem_fun (*this, &EditingContext::zoom_focus_chosen), Editing::ZoomFocusRight)); zoom_focus_actions[Editing::ZoomFocusRight] = radio_reg_sens (zoom_actions, zoom_group, "zoom-focus-right", _("Zoom Focus Right"), sigc::bind (sigc::mem_fun (*this, &EditingContext::zoom_focus_chosen), Editing::ZoomFocusRight));
radio_reg_sens (zoom_actions, zoom_group, "zoom-focus-center", _("Zoom Focus Center"), sigc::bind (sigc::mem_fun (*this, &EditingContext::zoom_focus_chosen), Editing::ZoomFocusCenter)); zoom_focus_actions[Editing::ZoomFocusCenter] = radio_reg_sens (zoom_actions, zoom_group, "zoom-focus-center", _("Zoom Focus Center"), sigc::bind (sigc::mem_fun (*this, &EditingContext::zoom_focus_chosen), Editing::ZoomFocusCenter));
radio_reg_sens (zoom_actions, zoom_group, "zoom-focus-playhead", _("Zoom Focus Playhead"), sigc::bind (sigc::mem_fun (*this, &EditingContext::zoom_focus_chosen), Editing::ZoomFocusPlayhead)); zoom_focus_actions[Editing::ZoomFocusPlayhead] = radio_reg_sens (zoom_actions, zoom_group, "zoom-focus-playhead", _("Zoom Focus Playhead"), sigc::bind (sigc::mem_fun (*this, &EditingContext::zoom_focus_chosen), Editing::ZoomFocusPlayhead));
radio_reg_sens (zoom_actions, zoom_group, "zoom-focus-mouse", _("Zoom Focus Mouse"), sigc::bind (sigc::mem_fun (*this, &EditingContext::zoom_focus_chosen), Editing::ZoomFocusMouse)); zoom_focus_actions[Editing::ZoomFocusMouse] = radio_reg_sens (zoom_actions, zoom_group, "zoom-focus-mouse", _("Zoom Focus Mouse"), sigc::bind (sigc::mem_fun (*this, &EditingContext::zoom_focus_chosen), Editing::ZoomFocusMouse));
radio_reg_sens (zoom_actions, zoom_group, "zoom-focus-edit", _("Zoom Focus Edit Point"), sigc::bind (sigc::mem_fun (*this, &EditingContext::zoom_focus_chosen), Editing::ZoomFocusEdit)); zoom_focus_actions[Editing::ZoomFocusEdit] = radio_reg_sens (zoom_actions, zoom_group, "zoom-focus-edit", _("Zoom Focus Edit Point"), sigc::bind (sigc::mem_fun (*this, &EditingContext::zoom_focus_chosen), Editing::ZoomFocusEdit));
ActionManager::register_action (zoom_actions, X_("cycle-zoom-focus"), _("Next Zoom Focus"), sigc::mem_fun (*this, &EditingContext::cycle_zoom_focus)); ActionManager::register_action (zoom_actions, X_("cycle-zoom-focus"), _("Next Zoom Focus"), sigc::mem_fun (*this, &EditingContext::cycle_zoom_focus));
@ -507,16 +536,16 @@ EditingContext::register_midi_actions (Bindings* midi_bindings, std::string cons
draw_length_actions[Editing::GridTypeBeatDiv14] = ActionManager::register_radio_action (length_actions, draw_length_group, X_("draw-length-fourteenths"), grid_type_strings[(int)GridTypeBeatDiv14].c_str(), sigc::bind (sigc::mem_fun (*this, &EditingContext::draw_length_chosen), Editing::GridTypeBeatDiv14)); draw_length_actions[Editing::GridTypeBeatDiv14] = ActionManager::register_radio_action (length_actions, draw_length_group, X_("draw-length-fourteenths"), grid_type_strings[(int)GridTypeBeatDiv14].c_str(), sigc::bind (sigc::mem_fun (*this, &EditingContext::draw_length_chosen), Editing::GridTypeBeatDiv14));
draw_length_actions[Editing::GridTypeBeatDiv12] = ActionManager::register_radio_action (length_actions, draw_length_group, X_("draw-length-twelfths"), grid_type_strings[(int)GridTypeBeatDiv12].c_str(), sigc::bind (sigc::mem_fun (*this, &EditingContext::draw_length_chosen), Editing::GridTypeBeatDiv12)); draw_length_actions[Editing::GridTypeBeatDiv12] = ActionManager::register_radio_action (length_actions, draw_length_group, X_("draw-length-twelfths"), grid_type_strings[(int)GridTypeBeatDiv12].c_str(), sigc::bind (sigc::mem_fun (*this, &EditingContext::draw_length_chosen), Editing::GridTypeBeatDiv12));
draw_length_actions[Editing::GridTypeBeatDiv10] = ActionManager::register_radio_action (length_actions, draw_length_group, X_("draw-length-tenths"), grid_type_strings[(int)GridTypeBeatDiv10].c_str(), sigc::bind (sigc::mem_fun (*this, &EditingContext::draw_length_chosen), Editing::GridTypeBeatDiv10)); draw_length_actions[Editing::GridTypeBeatDiv10] = ActionManager::register_radio_action (length_actions, draw_length_group, X_("draw-length-tenths"), grid_type_strings[(int)GridTypeBeatDiv10].c_str(), sigc::bind (sigc::mem_fun (*this, &EditingContext::draw_length_chosen), Editing::GridTypeBeatDiv10));
draw_length_actions[Editing::GridTypeBeatDiv8] = ActionManager::register_radio_action (length_actions, draw_length_group, X_("draw-length-eighths"), grid_type_strings[(int)GridTypeBeatDiv8].c_str(), sigc::bind (sigc::mem_fun (*this, &EditingContext::draw_length_chosen), Editing::GridTypeBeatDiv8)); draw_length_actions[Editing::GridTypeBeatDiv8] = ActionManager::register_radio_action (length_actions, draw_length_group, X_("draw-length-eighths"), grid_type_strings[(int)GridTypeBeatDiv8].c_str(), sigc::bind (sigc::mem_fun (*this, &EditingContext::draw_length_chosen), Editing::GridTypeBeatDiv8));
draw_length_actions[Editing::GridTypeBeatDiv7] = ActionManager::register_radio_action (length_actions, draw_length_group, X_("draw-length-sevenths"), grid_type_strings[(int)GridTypeBeatDiv7].c_str(), sigc::bind (sigc::mem_fun (*this, &EditingContext::draw_length_chosen), Editing::GridTypeBeatDiv7)); draw_length_actions[Editing::GridTypeBeatDiv7] = ActionManager::register_radio_action (length_actions, draw_length_group, X_("draw-length-sevenths"), grid_type_strings[(int)GridTypeBeatDiv7].c_str(), sigc::bind (sigc::mem_fun (*this, &EditingContext::draw_length_chosen), Editing::GridTypeBeatDiv7));
draw_length_actions[Editing::GridTypeBeatDiv6] = ActionManager::register_radio_action (length_actions, draw_length_group, X_("draw-length-sixths"), grid_type_strings[(int)GridTypeBeatDiv6].c_str(), sigc::bind (sigc::mem_fun (*this, &EditingContext::draw_length_chosen), Editing::GridTypeBeatDiv6)); draw_length_actions[Editing::GridTypeBeatDiv6] = ActionManager::register_radio_action (length_actions, draw_length_group, X_("draw-length-sixths"), grid_type_strings[(int)GridTypeBeatDiv6].c_str(), sigc::bind (sigc::mem_fun (*this, &EditingContext::draw_length_chosen), Editing::GridTypeBeatDiv6));
draw_length_actions[Editing::GridTypeBeatDiv5] = ActionManager::register_radio_action (length_actions, draw_length_group, X_("draw-length-fifths"), grid_type_strings[(int)GridTypeBeatDiv5].c_str(), sigc::bind (sigc::mem_fun (*this, &EditingContext::draw_length_chosen), Editing::GridTypeBeatDiv5)); draw_length_actions[Editing::GridTypeBeatDiv5] = ActionManager::register_radio_action (length_actions, draw_length_group, X_("draw-length-fifths"), grid_type_strings[(int)GridTypeBeatDiv5].c_str(), sigc::bind (sigc::mem_fun (*this, &EditingContext::draw_length_chosen), Editing::GridTypeBeatDiv5));
draw_length_actions[Editing::GridTypeBeatDiv4] = ActionManager::register_radio_action (length_actions, draw_length_group, X_("draw-length-quarters"), grid_type_strings[(int)GridTypeBeatDiv4].c_str(), sigc::bind (sigc::mem_fun (*this, &EditingContext::draw_length_chosen), Editing::GridTypeBeatDiv4)); draw_length_actions[Editing::GridTypeBeatDiv4] = ActionManager::register_radio_action (length_actions, draw_length_group, X_("draw-length-quarters"), grid_type_strings[(int)GridTypeBeatDiv4].c_str(), sigc::bind (sigc::mem_fun (*this, &EditingContext::draw_length_chosen), Editing::GridTypeBeatDiv4));
draw_length_actions[Editing::GridTypeBeatDiv3] = ActionManager::register_radio_action (length_actions, draw_length_group, X_("draw-length-thirds"), grid_type_strings[(int)GridTypeBeatDiv3].c_str(), sigc::bind (sigc::mem_fun (*this, &EditingContext::draw_length_chosen), Editing::GridTypeBeatDiv3)); draw_length_actions[Editing::GridTypeBeatDiv3] = ActionManager::register_radio_action (length_actions, draw_length_group, X_("draw-length-thirds"), grid_type_strings[(int)GridTypeBeatDiv3].c_str(), sigc::bind (sigc::mem_fun (*this, &EditingContext::draw_length_chosen), Editing::GridTypeBeatDiv3));
draw_length_actions[Editing::GridTypeBeatDiv2] = ActionManager::register_radio_action (length_actions, draw_length_group, X_("draw-length-halves"), grid_type_strings[(int)GridTypeBeatDiv2].c_str(), sigc::bind (sigc::mem_fun (*this, &EditingContext::draw_length_chosen), Editing::GridTypeBeatDiv2)); draw_length_actions[Editing::GridTypeBeatDiv2] = ActionManager::register_radio_action (length_actions, draw_length_group, X_("draw-length-halves"), grid_type_strings[(int)GridTypeBeatDiv2].c_str(), sigc::bind (sigc::mem_fun (*this, &EditingContext::draw_length_chosen), Editing::GridTypeBeatDiv2));
draw_length_actions[Editing::GridTypeBeat] = ActionManager::register_radio_action (length_actions, draw_length_group, X_("draw-length-beat"), grid_type_strings[(int)GridTypeBeat].c_str(), sigc::bind (sigc::mem_fun (*this, &EditingContext::draw_length_chosen), Editing::GridTypeBeat)); draw_length_actions[Editing::GridTypeBeat] = ActionManager::register_radio_action (length_actions, draw_length_group, X_("draw-length-beat"), grid_type_strings[(int)GridTypeBeat].c_str(), sigc::bind (sigc::mem_fun (*this, &EditingContext::draw_length_chosen), Editing::GridTypeBeat));
draw_length_actions[Editing::GridTypeBar] = ActionManager::register_radio_action (length_actions, draw_length_group, X_("draw-length-bar"), grid_type_strings[(int)GridTypeBar].c_str(), sigc::bind (sigc::mem_fun (*this, &EditingContext::draw_length_chosen), Editing::GridTypeBar)); draw_length_actions[Editing::GridTypeBar] = ActionManager::register_radio_action (length_actions, draw_length_group, X_("draw-length-bar"), grid_type_strings[(int)GridTypeBar].c_str(), sigc::bind (sigc::mem_fun (*this, &EditingContext::draw_length_chosen), Editing::GridTypeBar));
draw_length_actions[DRAW_LEN_AUTO] = ActionManager::register_radio_action (length_actions, draw_length_group, X_("draw-length-auto"), _("Auto"), sigc::bind (sigc::mem_fun (*this, &EditingContext::draw_length_chosen), DRAW_LEN_AUTO)); draw_length_actions[DRAW_LEN_AUTO] = ActionManager::register_radio_action (length_actions, draw_length_group, X_("draw-length-auto"), _("Auto"), sigc::bind (sigc::mem_fun (*this, &EditingContext::draw_length_chosen), DRAW_LEN_AUTO));
velocity_actions = ActionManager::create_action_group (midi_bindings, prefix + X_("DrawVelocity")); velocity_actions = ActionManager::create_action_group (midi_bindings, prefix + X_("DrawVelocity"));
RadioAction::Group draw_velocity_group; RadioAction::Group draw_velocity_group;
@ -673,8 +702,6 @@ EditingContext::grid_type_chosen (GridType gt)
auto ti = grid_actions.find (gt); auto ti = grid_actions.find (gt);
assert (ti != grid_actions.end()); assert (ti != grid_actions.end());
std::cerr << "gt chosen, type " << enum_2_string (gt) << " active ? " << ti->second->get_active () << std::endl;
if (!ti->second->get_active()) { if (!ti->second->get_active()) {
return; return;
} }
@ -701,11 +728,10 @@ EditingContext::grid_type_chosen (GridType gt)
compute_bbt_ruler_scale (_leftmost_sample, _leftmost_sample + current_page_samples()); compute_bbt_ruler_scale (_leftmost_sample, _leftmost_sample + current_page_samples());
update_tempo_based_rulers (); update_tempo_based_rulers ();
} else if (current_mouse_mode () == Editing::MouseGrid) { } else if (current_mouse_mode () == Editing::MouseGrid) {
Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic (get_mouse_mode_action (Editing::MouseObject)); mouse_mode_actions[Editing::MouseObject]->set_active (true);
ract->set_active (true);
} }
get_mouse_mode_action (Editing::MouseGrid)->set_sensitive (grid_is_musical); mouse_mode_actions[Editing::MouseGrid]->set_sensitive (grid_is_musical);
mark_region_boundary_cache_dirty (); mark_region_boundary_cache_dirty ();
@ -728,7 +754,7 @@ EditingContext::draw_length_chosen (GridType type)
return; return;
} }
if (!grid_type_is_musical (type) ) { // is this is sensible sanity check ? if ((DRAW_LEN_AUTO != type) && !grid_type_is_musical (type) ) { // is this is sensible sanity check ?
set_draw_length (DRAW_LEN_AUTO); set_draw_length (DRAW_LEN_AUTO);
return; return;
} }
@ -830,10 +856,7 @@ EditingContext::snap_mode_chosen (SnapMode mode)
mode = SnapMagnetic; mode = SnapMagnetic;
} }
auto si = snap_mode_actions.find (mode); if (!snap_mode_actions[mode]->get_active()) {
assert (si != snap_mode_actions.end());
if (!si->second->get_active()) {
return; return;
} }
@ -1144,8 +1167,13 @@ EditingContext::time_domain () const
void void
EditingContext::toggle_follow_playhead () EditingContext::toggle_follow_playhead ()
{ {
RefPtr<ToggleAction> tact = ActionManager::get_toggle_action ((_name + X_("Editing")).c_str(), X_("toggle-follow-playhead")); set_follow_playhead (!follow_playhead_action->get_active(), true);
set_follow_playhead (tact->get_active()); }
void
EditingContext::follow_playhead_chosen ()
{
instant_save ();
} }
/** @param yn true to follow playhead, otherwise false. /** @param yn true to follow playhead, otherwise false.
@ -1155,14 +1183,10 @@ void
EditingContext::set_follow_playhead (bool yn, bool catch_up) EditingContext::set_follow_playhead (bool yn, bool catch_up)
{ {
assert (follow_playhead_action); assert (follow_playhead_action);
if (follow_playhead() != yn) { follow_playhead_action->set_active (yn);
follow_playhead_action->set_active (yn); if (yn && catch_up) {
if (yn && catch_up) { /* catch up */
/* catch up */ reset_x_origin_to_follow_playhead ();
reset_x_origin_to_follow_playhead ();
}
std::cerr << editor_name() << " SFP instant save\n";
instant_save ();
} }
} }
@ -1969,28 +1993,6 @@ EditingContext::pack_snap_box ()
snap_box.pack_start (grid_type_selector, false, false); snap_box.pack_start (grid_type_selector, false, false);
} }
Glib::RefPtr<Action>
EditingContext::get_mouse_mode_action (MouseMode m) const
{
switch (m) {
case MouseRange:
return ActionManager::get_action ((_name + X_("Editing")).c_str(), X_("set-mouse-mode-range"));
case MouseObject:
return ActionManager::get_action ((_name + X_("Editing")).c_str(), X_("set-mouse-mode-object"));
case MouseCut:
return ActionManager::get_action ((_name + X_("Editing")).c_str(), X_("set-mouse-mode-cut"));
case MouseDraw:
return ActionManager::get_action ((_name + X_("Editing")).c_str(), X_("set-mouse-mode-draw"));
case MouseTimeFX:
return ActionManager::get_action ((_name + X_("Editing")).c_str(), X_("set-mouse-mode-timefx"));
case MouseGrid:
return ActionManager::get_action ((_name + X_("Editing")).c_str(), X_("set-mouse-mode-grid"));
case MouseContent:
return ActionManager::get_action ((_name + X_("Editing")).c_str(), X_("set-mouse-mode-content"));
}
return Glib::RefPtr<Action>();
}
void void
EditingContext::bind_mouse_mode_buttons () EditingContext::bind_mouse_mode_buttons ()
{ {
@ -2001,37 +2003,36 @@ EditingContext::bind_mouse_mode_buttons ()
act = ActionManager::get_action ((_name + X_("Editing")).c_str(), X_("temporal-zoom-out")); act = ActionManager::get_action ((_name + X_("Editing")).c_str(), X_("temporal-zoom-out"));
zoom_out_button.set_related_action (act); zoom_out_button.set_related_action (act);
act = ActionManager::get_action ((_name + X_("Editing")).c_str(), X_("toggle-follow-playhead")); follow_playhead_button.set_related_action (follow_playhead_action);
follow_playhead_button.set_related_action (act);
act = ActionManager::get_action (X_("Transport"), X_("ToggleFollowEdits")); act = ActionManager::get_action (X_("Transport"), X_("ToggleFollowEdits"));
follow_edits_button.set_related_action (act); follow_edits_button.set_related_action (act);
mouse_move_button.set_related_action (get_mouse_mode_action (Editing::MouseObject)); mouse_move_button.set_related_action (mouse_mode_actions[Editing::MouseObject]);
mouse_move_button.set_icon (ArdourWidgets::ArdourIcon::ToolGrab); mouse_move_button.set_icon (ArdourWidgets::ArdourIcon::ToolGrab);
mouse_move_button.set_name ("mouse mode button"); mouse_move_button.set_name ("mouse mode button");
mouse_select_button.set_related_action (get_mouse_mode_action (Editing::MouseRange)); mouse_select_button.set_related_action (mouse_mode_actions[Editing::MouseRange]);
mouse_select_button.set_icon (ArdourWidgets::ArdourIcon::ToolRange); mouse_select_button.set_icon (ArdourWidgets::ArdourIcon::ToolRange);
mouse_select_button.set_name ("mouse mode button"); mouse_select_button.set_name ("mouse mode button");
mouse_draw_button.set_related_action (get_mouse_mode_action (Editing::MouseDraw)); mouse_draw_button.set_related_action (mouse_mode_actions[Editing::MouseDraw]);
mouse_draw_button.set_icon (ArdourWidgets::ArdourIcon::ToolDraw); mouse_draw_button.set_icon (ArdourWidgets::ArdourIcon::ToolDraw);
mouse_draw_button.set_name ("mouse mode button"); mouse_draw_button.set_name ("mouse mode button");
mouse_timefx_button.set_related_action (get_mouse_mode_action (Editing::MouseTimeFX)); mouse_timefx_button.set_related_action (mouse_mode_actions[Editing::MouseTimeFX]);
mouse_timefx_button.set_icon (ArdourWidgets::ArdourIcon::ToolStretch); mouse_timefx_button.set_icon (ArdourWidgets::ArdourIcon::ToolStretch);
mouse_timefx_button.set_name ("mouse mode button"); mouse_timefx_button.set_name ("mouse mode button");
mouse_grid_button.set_related_action (get_mouse_mode_action (Editing::MouseGrid)); mouse_grid_button.set_related_action (mouse_mode_actions[Editing::MouseGrid]);
mouse_grid_button.set_icon (ArdourWidgets::ArdourIcon::ToolGrid); mouse_grid_button.set_icon (ArdourWidgets::ArdourIcon::ToolGrid);
mouse_grid_button.set_name ("mouse mode button"); mouse_grid_button.set_name ("mouse mode button");
mouse_content_button.set_related_action (get_mouse_mode_action (Editing::MouseContent)); mouse_content_button.set_related_action (mouse_mode_actions[Editing::MouseContent]);
mouse_content_button.set_icon (ArdourWidgets::ArdourIcon::ToolContent); mouse_content_button.set_icon (ArdourWidgets::ArdourIcon::ToolContent);
mouse_content_button.set_name ("mouse mode button"); mouse_content_button.set_name ("mouse mode button");
mouse_cut_button.set_related_action (get_mouse_mode_action (Editing::MouseCut)); mouse_cut_button.set_related_action (mouse_mode_actions[Editing::MouseCut]);
mouse_cut_button.set_icon (ArdourWidgets::ArdourIcon::ToolCut); mouse_cut_button.set_icon (ArdourWidgets::ArdourIcon::ToolCut);
mouse_cut_button.set_name ("mouse mode button"); mouse_cut_button.set_name ("mouse mode button");
@ -2044,6 +2045,18 @@ EditingContext::bind_mouse_mode_buttons ()
set_tooltip (mouse_content_button, _("Internal Edit Mode (edit notes and automation points)")); set_tooltip (mouse_content_button, _("Internal Edit Mode (edit notes and automation points)"));
} }
Editing::MouseMode
EditingContext::current_mouse_mode() const
{
for (auto & [mode,action] : mouse_mode_actions) {
if (action->get_active()) {
return mode;
}
}
return MouseObject;
}
void void
EditingContext::set_mouse_mode (MouseMode m, bool force) EditingContext::set_mouse_mode (MouseMode m, bool force)
{ {
@ -2051,21 +2064,13 @@ EditingContext::set_mouse_mode (MouseMode m, bool force)
return; return;
} }
if (!force && m == mouse_mode) { if (force && mouse_mode_actions[m]->get_active()) {
return; mouse_mode_actions[m]->set_active (false);
} }
Glib::RefPtr<Action> act = get_mouse_mode_action(m); mouse_mode_actions[m]->set_active (true);
Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
/* go there and back to ensure that the toggled handler is called to set up mouse_mode */
tact->set_active (false);
tact->set_active (true);
/* NOTE: this will result in a call to mouse_mode_toggled which does the heavy lifting */
} }
bool bool
EditingContext::on_velocity_scroll_event (GdkEventScroll* ev) EditingContext::on_velocity_scroll_event (GdkEventScroll* ev)
{ {
@ -2545,7 +2550,7 @@ EditingContext::follow_playhead_clicked ()
void void
EditingContext::cycle_zoom_focus () EditingContext::cycle_zoom_focus ()
{ {
switch (_zoom_focus) { switch (zoom_focus()) {
case ZoomFocusLeft: case ZoomFocusLeft:
set_zoom_focus (ZoomFocusRight); set_zoom_focus (ZoomFocusRight);
break; break;
@ -2570,7 +2575,8 @@ EditingContext::cycle_zoom_focus ()
void void
EditingContext::temporal_zoom_step_mouse_focus_scale (bool zoom_out, double scale) EditingContext::temporal_zoom_step_mouse_focus_scale (bool zoom_out, double scale)
{ {
PBD::Unwinder<Editing::ZoomFocus> zf (_zoom_focus, Editing::ZoomFocusMouse); #warning paul how to unwind a failed attempt here
// PBD::Unwinder<Editing::ZoomFocus> zf (zoom_focus(), Editing::ZoomFocusMouse);
temporal_zoom_step_scale (zoom_out, scale); temporal_zoom_step_scale (zoom_out, scale);
} }
@ -2931,47 +2937,16 @@ EditingContext::window_event_sample (GdkEvent const * event, double* pcx, double
return pixel_to_sample (canvas_to_timeline (d.x)); return pixel_to_sample (canvas_to_timeline (d.x));
} }
void Editing::ZoomFocus
EditingContext::zoom_focus_selection_done (ZoomFocus f) EditingContext::zoom_focus () const
{ {
RefPtr<RadioAction> ract = zoom_focus_action (f); for (auto & [mode,action] : zoom_focus_actions) {
if (ract) { if (action->get_active()) {
ract->set_active (); return mode;
} }
}
RefPtr<RadioAction>
EditingContext::zoom_focus_action (ZoomFocus focus)
{
const char* action = 0;
RefPtr<Action> act;
switch (focus) {
case ZoomFocusLeft:
action = X_("zoom-focus-left");
break;
case ZoomFocusRight:
action = X_("zoom-focus-right");
break;
case ZoomFocusCenter:
action = X_("zoom-focus-center");
break;
case ZoomFocusPlayhead:
action = X_("zoom-focus-playhead");
break;
case ZoomFocusMouse:
action = X_("zoom-focus-mouse");
break;
case ZoomFocusEdit:
action = X_("zoom-focus-edit");
break;
default:
fatal << string_compose (_("programming error: %1: %2"), "Editor: impossible focus type", (int) focus) << endmsg;
abort(); /*NOTREACHED*/
} }
return ZoomFocusLeft;
return ActionManager::get_radio_action ((_name + X_("Zoom")).c_str(), action);
} }
void void
@ -2982,11 +2957,13 @@ EditingContext::zoom_focus_chosen (ZoomFocus focus)
active. active.
*/ */
RefPtr<RadioAction> ract = zoom_focus_action (focus); if (!zoom_focus_actions[focus]->get_active()) {
return;
if (ract && ract->get_active()) {
set_zoom_focus (focus);
} }
zoom_focus_selector.set_active (zoom_focus_strings[(int)focus]);
instant_save ();
} }
void void
@ -3152,6 +3129,7 @@ EditingContext::set_loop_range (timepos_t const & start, timepos_t const & end,
bool bool
EditingContext::allow_trim_cursors () const EditingContext::allow_trim_cursors () const
{ {
auto mouse_mode = current_mouse_mode();
return mouse_mode == MouseContent || mouse_mode == MouseTimeFX || mouse_mode == MouseDraw; return mouse_mode == MouseContent || mouse_mode == MouseTimeFX || mouse_mode == MouseDraw;
} }

View file

@ -332,12 +332,9 @@ class EditingContext : public ARDOUR::SessionHandlePtr, public AxisViewProvider,
virtual void cycle_zoom_focus (); virtual void cycle_zoom_focus ();
virtual void set_zoom_focus (Editing::ZoomFocus) = 0; virtual void set_zoom_focus (Editing::ZoomFocus) = 0;
Editing::ZoomFocus zoom_focus () const { return _zoom_focus; } Editing::ZoomFocus zoom_focus () const;
sigc::signal<void> ZoomFocusChanged;
void zoom_focus_selection_done (Editing::ZoomFocus);
void zoom_focus_chosen (Editing::ZoomFocus); void zoom_focus_chosen (Editing::ZoomFocus);
Glib::RefPtr<Gtk::RadioAction> zoom_focus_action (Editing::ZoomFocus);
virtual void reposition_and_zoom (samplepos_t, double) = 0; virtual void reposition_and_zoom (samplepos_t, double) = 0;
@ -363,8 +360,8 @@ class EditingContext : public ARDOUR::SessionHandlePtr, public AxisViewProvider,
/** @return The current mouse mode (gain, object, range, timefx etc.) /** @return The current mouse mode (gain, object, range, timefx etc.)
* (defined in editing_syms.inc.h) * (defined in editing_syms.inc.h)
*/ */
Editing::MouseMode current_mouse_mode () const { return mouse_mode; } Editing::MouseMode current_mouse_mode () const;
virtual Editing::MouseMode effective_mouse_mode () const { return mouse_mode; } virtual Editing::MouseMode effective_mouse_mode () const { return current_mouse_mode(); }
virtual void use_appropriate_mouse_mode_for_sections () {} virtual void use_appropriate_mouse_mode_for_sections () {}
/** @return Whether the current mouse mode is an "internal" editing mode. */ /** @return Whether the current mouse mode is an "internal" editing mode. */
@ -426,6 +423,7 @@ class EditingContext : public ARDOUR::SessionHandlePtr, public AxisViewProvider,
void register_midi_actions (Gtkmm2ext::Bindings*, std::string const &); void register_midi_actions (Gtkmm2ext::Bindings*, std::string const &);
void register_common_actions (Gtkmm2ext::Bindings*, std::string const &); void register_common_actions (Gtkmm2ext::Bindings*, std::string const &);
void register_automation_actions (Gtkmm2ext::Bindings*, std::string const &); void register_automation_actions (Gtkmm2ext::Bindings*, std::string const &);
void set_action_defaults ();
ArdourCanvas::Rectangle* rubberband_rect; ArdourCanvas::Rectangle* rubberband_rect;
@ -445,7 +443,7 @@ class EditingContext : public ARDOUR::SessionHandlePtr, public AxisViewProvider,
virtual ArdourCanvas::GtkCanvasViewport* get_canvas_viewport() const = 0; virtual ArdourCanvas::GtkCanvasViewport* get_canvas_viewport() const = 0;
virtual ArdourCanvas::GtkCanvas* get_canvas() const = 0; virtual ArdourCanvas::GtkCanvas* get_canvas() const = 0;
virtual void mouse_mode_toggled (Editing::MouseMode) = 0; virtual void mouse_mode_chosen (Editing::MouseMode) = 0;
bool on_velocity_scroll_event (GdkEventScroll*); bool on_velocity_scroll_event (GdkEventScroll*);
void pre_render (); void pre_render ();
@ -531,6 +529,8 @@ class EditingContext : public ARDOUR::SessionHandlePtr, public AxisViewProvider,
std::map<Editing::GridType, Glib::RefPtr<Gtk::RadioAction> > grid_actions; std::map<Editing::GridType, Glib::RefPtr<Gtk::RadioAction> > grid_actions;
std::map<Editing::SnapMode, Glib::RefPtr<Gtk::RadioAction> > snap_mode_actions; std::map<Editing::SnapMode, Glib::RefPtr<Gtk::RadioAction> > snap_mode_actions;
std::map<Editing::GridType, Glib::RefPtr<Gtk::RadioAction> > draw_length_actions; std::map<Editing::GridType, Glib::RefPtr<Gtk::RadioAction> > draw_length_actions;
std::map<Editing::MouseMode, Glib::RefPtr<Gtk::RadioAction> > mouse_mode_actions;
std::map<Editing::ZoomFocus, Glib::RefPtr<Gtk::RadioAction> > zoom_focus_actions;
std::map<int, Glib::RefPtr<Gtk::RadioAction> > draw_velocity_actions; std::map<int, Glib::RefPtr<Gtk::RadioAction> > draw_velocity_actions;
std::map<int, Glib::RefPtr<Gtk::RadioAction> > draw_channel_actions; std::map<int, Glib::RefPtr<Gtk::RadioAction> > draw_channel_actions;
@ -594,6 +594,7 @@ class EditingContext : public ARDOUR::SessionHandlePtr, public AxisViewProvider,
EditorCursor* _snapped_cursor; EditorCursor* _snapped_cursor;
Glib::RefPtr<Gtk::ToggleAction> follow_playhead_action; Glib::RefPtr<Gtk::ToggleAction> follow_playhead_action;
void follow_playhead_chosen ();
/* selection process */ /* selection process */
@ -608,8 +609,8 @@ class EditingContext : public ARDOUR::SessionHandlePtr, public AxisViewProvider,
VerboseCursor* _verbose_cursor; VerboseCursor* _verbose_cursor;
samplecnt_t samples_per_pixel; samplecnt_t samples_per_pixel;
Editing::ZoomFocus _zoom_focus;
virtual Editing::ZoomFocus effective_zoom_focus() const { return _zoom_focus; } virtual Editing::ZoomFocus effective_zoom_focus() const { return zoom_focus(); }
Temporal::timepos_t snap_to_bbt_via_grid (Temporal::timepos_t const & start, Temporal::timepos_t snap_to_bbt_via_grid (Temporal::timepos_t const & start,
Temporal::RoundMode direction, Temporal::RoundMode direction,
@ -698,7 +699,6 @@ class EditingContext : public ARDOUR::SessionHandlePtr, public AxisViewProvider,
virtual void register_actions() = 0; virtual void register_actions() = 0;
void register_grid_actions (); void register_grid_actions ();
Glib::RefPtr<Gtk::Action> get_mouse_mode_action (Editing::MouseMode m) const;
void bind_mouse_mode_buttons (); void bind_mouse_mode_buttons ();
Gtk::HBox snap_box; Gtk::HBox snap_box;
@ -714,8 +714,6 @@ class EditingContext : public ARDOUR::SessionHandlePtr, public AxisViewProvider,
Gtkmm2ext::BindingSet bindings; Gtkmm2ext::BindingSet bindings;
Gtkmm2ext::Bindings* own_bindings; Gtkmm2ext::Bindings* own_bindings;
Editing::MouseMode mouse_mode;
void set_common_editing_state (XMLNode const & node); void set_common_editing_state (XMLNode const & node);
void get_common_editing_state (XMLNode& node) const; void get_common_editing_state (XMLNode& node) const;

View file

@ -654,6 +654,7 @@ Editor::Editor ()
load_bindings (); load_bindings ();
register_actions (); register_actions ();
bind_mouse_mode_buttons (); bind_mouse_mode_buttons ();
set_action_defaults ();
build_edit_mode_menu(); build_edit_mode_menu();
build_zoom_focus_menu(); build_zoom_focus_menu();
@ -2199,8 +2200,11 @@ Editor::set_state (const XMLNode& node, int version)
node.get_property ("mixer-width", editor_mixer_strip_width); node.get_property ("mixer-width", editor_mixer_strip_width);
node.get_property ("zoom-focus", _zoom_focus); ZoomFocus zf;
zoom_focus_selection_done (_zoom_focus); if (!node.get_property ("zoom-focus", zf)) {
zf = ZoomFocusLeft;
}
set_zoom_preset (zf);
node.get_property ("marker-click-behavior", marker_click_behavior); node.get_property ("marker-click-behavior", marker_click_behavior);
marker_click_behavior_selection_done (marker_click_behavior); marker_click_behavior_selection_done (marker_click_behavior);
@ -2223,7 +2227,7 @@ Editor::set_state (const XMLNode& node, int version)
/* do it twice to force the change */ /* do it twice to force the change */
smart_mode_action->set_active (!yn); smart_mode_action->set_active (!yn);
smart_mode_action->set_active (yn); smart_mode_action->set_active (yn);
set_mouse_mode (mouse_mode, true); set_mouse_mode (current_mouse_mode(), true);
} }
EditPoint ep; EditPoint ep;
@ -2316,26 +2320,6 @@ Editor::set_state (const XMLNode& node, int version)
nudge_clock->set_duration (timecnt_t (_session->sample_rate() * 5), true); nudge_clock->set_duration (timecnt_t (_session->sample_rate() * 5), true);
} }
{
/* apply state
* Not all properties may have been in XML, but
* those that are linked to a private variable may need changing
*/
RefPtr<ToggleAction> tact;
tact = ActionManager::get_toggle_action ((editor_name () + X_("Editing")).c_str(), X_("toggle-follow-playhead"));
yn = follow_playhead();
if (tact->get_active() != yn) {
tact->set_active (yn);
}
tact = ActionManager::get_toggle_action (X_("Editor"), X_("toggle-stationary-playhead"));
yn = _stationary_playhead;
if (tact->get_active() != yn) {
tact->set_active (yn);
}
}
return 0; return 0;
} }
@ -2352,7 +2336,7 @@ Editor::get_state () const
maybe_add_mixer_strip_width (*node); maybe_add_mixer_strip_width (*node);
node->set_property ("zoom-focus", _zoom_focus); node->set_property ("zoom-focus", zoom_focus());
node->set_property ("edit-point", _edit_point); node->set_property ("edit-point", _edit_point);
node->set_property ("visible-track-count", _visible_track_count); node->set_property ("visible-track-count", _visible_track_count);
@ -2366,7 +2350,7 @@ Editor::get_state () const
node->set_property ("maximised", _maximised); node->set_property ("maximised", _maximised);
node->set_property ("follow-playhead", follow_playhead()); node->set_property ("follow-playhead", follow_playhead());
node->set_property ("stationary-playhead", _stationary_playhead); node->set_property ("stationary-playhead", _stationary_playhead);
node->set_property ("mouse-mode", mouse_mode); node->set_property ("mouse-mode", current_mouse_mode());
node->set_property ("join-object-range", smart_mode_action->get_active ()); node->set_property ("join-object-range", smart_mode_action->get_active ());
node->set_property (X_("show-editor-mixer"), show_editor_mixer_action->get_active()); node->set_property (X_("show-editor-mixer"), show_editor_mixer_action->get_active());
@ -3210,12 +3194,12 @@ Editor::build_zoom_focus_menu ()
{ {
using namespace Menu_Helpers; using namespace Menu_Helpers;
zoom_focus_selector.add_menu_elem (MenuElem (zoom_focus_strings[(int)ZoomFocusLeft], sigc::bind (sigc::mem_fun(*this, &EditingContext::zoom_focus_selection_done), (ZoomFocus) ZoomFocusLeft))); zoom_focus_selector.append (zoom_focus_actions[ZoomFocusLeft]);
zoom_focus_selector.add_menu_elem (MenuElem (zoom_focus_strings[(int)ZoomFocusRight], sigc::bind (sigc::mem_fun(*this, &EditingContext::zoom_focus_selection_done), (ZoomFocus) ZoomFocusRight))); zoom_focus_selector.append (zoom_focus_actions[ZoomFocusRight]);
zoom_focus_selector.add_menu_elem (MenuElem (zoom_focus_strings[(int)ZoomFocusCenter], sigc::bind (sigc::mem_fun(*this, &EditingContext::zoom_focus_selection_done), (ZoomFocus) ZoomFocusCenter))); zoom_focus_selector.append (zoom_focus_actions[ZoomFocusCenter]);
zoom_focus_selector.add_menu_elem (MenuElem (zoom_focus_strings[(int)ZoomFocusPlayhead], sigc::bind (sigc::mem_fun(*this, &EditingContext::zoom_focus_selection_done), (ZoomFocus) ZoomFocusPlayhead))); zoom_focus_selector.append (zoom_focus_actions[ZoomFocusPlayhead]);
zoom_focus_selector.add_menu_elem (MenuElem (zoom_focus_strings[(int)ZoomFocusMouse], sigc::bind (sigc::mem_fun(*this, &EditingContext::zoom_focus_selection_done), (ZoomFocus) ZoomFocusMouse))); zoom_focus_selector.append (zoom_focus_actions[ZoomFocusMouse]);
zoom_focus_selector.add_menu_elem (MenuElem (zoom_focus_strings[(int)ZoomFocusEdit], sigc::bind (sigc::mem_fun(*this, &EditingContext::zoom_focus_selection_done), (ZoomFocus) ZoomFocusEdit))); zoom_focus_selector.append (zoom_focus_actions[ZoomFocusEdit]);
zoom_focus_selector.set_sizing_texts (zoom_focus_strings); zoom_focus_selector.set_sizing_texts (zoom_focus_strings);
} }
@ -3384,17 +3368,7 @@ Editor::mouse_select_button_release (GdkEventButton* ev)
void void
Editor::set_zoom_focus (ZoomFocus f) Editor::set_zoom_focus (ZoomFocus f)
{ {
string str = zoom_focus_strings[(int)f]; zoom_focus_actions[f]->set_active (true);
if (str != zoom_focus_selector.get_text()) {
zoom_focus_selector.set_text (str);
}
if (_zoom_focus != f) {
_zoom_focus = f;
instant_save ();
ZoomFocusChanged (); /* EMIT SIGNAL */
}
} }
void void
@ -3812,7 +3786,7 @@ Editor::current_visual_state (bool with_tracks)
vs->y_position = vertical_adjustment.get_value(); vs->y_position = vertical_adjustment.get_value();
vs->samples_per_pixel = samples_per_pixel; vs->samples_per_pixel = samples_per_pixel;
vs->_leftmost_sample = _leftmost_sample; vs->_leftmost_sample = _leftmost_sample;
vs->zoom_focus = _zoom_focus; vs->zoom_focus = zoom_focus();
if (with_tracks) { if (with_tracks) {
vs->gui_state->set_state (ARDOUR_UI::instance()->gui_object_state->get_state()); vs->gui_state->set_state (ARDOUR_UI::instance()->gui_object_state->get_state());

View file

@ -1768,7 +1768,7 @@ private:
ArdourWidgets::ArdourButton smart_mode_button; ArdourWidgets::ArdourButton smart_mode_button;
Glib::RefPtr<Gtk::ToggleAction> smart_mode_action; Glib::RefPtr<Gtk::ToggleAction> smart_mode_action;
void mouse_mode_toggled (Editing::MouseMode m); void mouse_mode_chosen (Editing::MouseMode m);
void mouse_mode_object_range_toggled (); void mouse_mode_object_range_toggled ();
bool ignore_mouse_mode_toggle; bool ignore_mouse_mode_toggle;

View file

@ -1123,7 +1123,7 @@ Editor::which_mode_cursor () const
{ {
Gdk::Cursor* mode_cursor = MouseCursors::invalid_cursor (); Gdk::Cursor* mode_cursor = MouseCursors::invalid_cursor ();
switch (mouse_mode) { switch (current_mouse_mode()) {
case MouseRange: case MouseRange:
mode_cursor = _cursors->selector; mode_cursor = _cursors->selector;
break; break;
@ -1213,6 +1213,7 @@ Gdk::Cursor*
Editor::which_canvas_cursor(ItemType type) const Editor::which_canvas_cursor(ItemType type) const
{ {
Gdk::Cursor* cursor = which_mode_cursor (); Gdk::Cursor* cursor = which_mode_cursor ();
auto mouse_mode = current_mouse_mode();
if (mouse_mode == MouseRange) { if (mouse_mode == MouseRange) {
switch (type) { switch (type) {
@ -1385,6 +1386,7 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
TempoMarker* t_marker = 0; TempoMarker* t_marker = 0;
double fraction; double fraction;
bool ret = true; bool ret = true;
auto mouse_mode = current_mouse_mode();
/* by the time we reach here, entered_regionview and entered trackview /* by the time we reach here, entered_regionview and entered trackview
* will have already been set as appropriate. Things are done this * will have already been set as appropriate. Things are done this

View file

@ -121,16 +121,13 @@ Editor::set_current_movable (std::shared_ptr<Movable> m)
void void
Editor::mouse_mode_object_range_toggled() Editor::mouse_mode_object_range_toggled()
{ {
set_mouse_mode (mouse_mode, true); /* updates set-mouse-mode-range */ set_mouse_mode (current_mouse_mode(), true); /* updates set-mouse-mode-range */
} }
void void
Editor::mouse_mode_toggled (MouseMode m) Editor::mouse_mode_chosen (MouseMode m)
{ {
Glib::RefPtr<Action> act = get_mouse_mode_action(m); if (!mouse_mode_actions[m]->get_active()) {
Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
if (!tact->get_active()) {
/* this was just the notification that the old mode has been /* this was just the notification that the old mode has been
* left. we'll get called again with the new mode active in a * left. we'll get called again with the new mode active in a
* jiffy. * jiffy.
@ -140,8 +137,6 @@ Editor::mouse_mode_toggled (MouseMode m)
const bool was_internal = internal_editing(); const bool was_internal = internal_editing();
mouse_mode = m;
/* Ben ToDo: once we have a dedicated 'region edit panel', we can store /* Ben ToDo: once we have a dedicated 'region edit panel', we can store
* one snap mode in the editor canvas and another one in the editor, * one snap mode in the editor canvas and another one in the editor,
* relieving the complexity here */ * relieving the complexity here */
@ -174,6 +169,8 @@ Editor::mouse_mode_toggled (MouseMode m)
update_time_selection_display (); update_time_selection_display ();
auto mouse_mode = current_mouse_mode ();
if (mouse_mode == MouseDraw) { if (mouse_mode == MouseDraw) {
draw_box.show(); draw_box.show();
_draw_box_spacer.show(); _draw_box_spacer.show();
@ -239,12 +236,14 @@ Editor::mouse_mode_toggled (MouseMode m)
bool bool
Editor::internal_editing() const Editor::internal_editing() const
{ {
auto mouse_mode = current_mouse_mode ();
return mouse_mode == Editing::MouseContent || mouse_mode == Editing::MouseDraw; return mouse_mode == Editing::MouseContent || mouse_mode == Editing::MouseDraw;
} }
void void
Editor::update_time_selection_display () Editor::update_time_selection_display ()
{ {
auto mouse_mode = current_mouse_mode ();
switch (mouse_mode) { switch (mouse_mode) {
case MouseRange: case MouseRange:
selection->clear_objects (); selection->clear_objects ();
@ -328,6 +327,7 @@ Editor::button_selection (ArdourCanvas::Item* item, GdkEvent* event, ItemType it
*/ */
MouseMode eff_mouse_mode = effective_mouse_mode (); MouseMode eff_mouse_mode = effective_mouse_mode ();
auto mouse_mode = current_mouse_mode ();
if (eff_mouse_mode == MouseCut) { if (eff_mouse_mode == MouseCut) {
/* never change selection in cut mode */ /* never change selection in cut mode */
@ -1751,6 +1751,8 @@ Editor::determine_mapping_grid_snap (timepos_t t)
bool bool
Editor::motion_handler (ArdourCanvas::Item* item, GdkEvent* event, bool from_autoscroll) Editor::motion_handler (ArdourCanvas::Item* item, GdkEvent* event, bool from_autoscroll)
{ {
auto mouse_mode = current_mouse_mode ();
_last_motion_y = event->motion.y; _last_motion_y = event->motion.y;
if (event->motion.is_hint) { if (event->motion.is_hint) {
@ -2274,6 +2276,8 @@ Editor::escape ()
void void
Editor::update_join_object_range_location (double y) Editor::update_join_object_range_location (double y)
{ {
auto mouse_mode = current_mouse_mode ();
if (!get_smart_mode()) { if (!get_smart_mode()) {
_join_object_range_state = JOIN_OBJECT_RANGE_NONE; _join_object_range_state = JOIN_OBJECT_RANGE_NONE;
return; return;
@ -2352,7 +2356,7 @@ Editor::effective_mouse_mode () const
return MouseRange; return MouseRange;
} }
return mouse_mode; return current_mouse_mode ();
} }
void void
@ -2382,16 +2386,7 @@ Editor::use_appropriate_mouse_mode_for_sections ()
/*fallthrough*/ /*fallthrough*/
default: default:
/* switch to range mode */ /* switch to range mode */
Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_static (get_mouse_mode_action (Editing::MouseRange)); mouse_mode_actions[Editing::MouseRange]->set_active (true);
if (!ract) {
/* missing action */
fatal << X_("programming error: missing mouse-mode-range action") << endmsg;
/*NOTREACHED*/
break;
}
if (ract) {
ract->set_active (true);
}
break; break;
} }
} }
@ -2417,6 +2412,7 @@ Editor::get_pointer_position (double& x, double& y) const
void void
Editor::choose_mapping_drag (ArdourCanvas::Item* item, GdkEvent* event) Editor::choose_mapping_drag (ArdourCanvas::Item* item, GdkEvent* event)
{ {
/* In a departure from convention, this event is not handled by a widget /* In a departure from convention, this event is not handled by a widget
* 'on' the ruler-bar, like a tempo marker, but is instead handled by the * 'on' the ruler-bar, like a tempo marker, but is instead handled by the
* whole canvas. The intent is for the user to feel that they * whole canvas. The intent is for the user to feel that they
@ -2433,6 +2429,8 @@ Editor::choose_mapping_drag (ArdourCanvas::Item* item, GdkEvent* event)
/* if tempo-mapping, set a cursor to indicate whether we are close to a bar line, beat line, or neither */ /* if tempo-mapping, set a cursor to indicate whether we are close to a bar line, beat line, or neither */
bool ramped = false; bool ramped = false;
auto mouse_mode = current_mouse_mode ();
if (mouse_mode == MouseGrid && item ==_canvas_grid_zone) { if (mouse_mode == MouseGrid && item ==_canvas_grid_zone) {
GridType gt = determine_mapping_grid_snap (timepos_t (where)); GridType gt = determine_mapping_grid_snap (timepos_t (where));
if (gt == GridTypeBar) { if (gt == GridTypeBar) {

View file

@ -380,7 +380,7 @@ Editor::split_regions_at (timepos_t const & where, RegionSelection& regions)
} }
//if the user wants newly-created regions to be selected, then select them: //if the user wants newly-created regions to be selected, then select them:
if (mouse_mode == MouseObject) { if (current_mouse_mode() == MouseObject) {
for (RegionSelection::iterator ri = latest_regionviews.begin(); ri != latest_regionviews.end(); ri++) { for (RegionSelection::iterator ri = latest_regionviews.begin(); ri != latest_regionviews.end(); ri++) {
if ((*ri)->region()->position() < where) { if ((*ri)->region()->position() < where) {
// new regions created before the split // new regions created before the split
@ -1201,7 +1201,7 @@ Editor::cursor_to_selection_start (EditorCursor *cursor)
{ {
timepos_t pos; timepos_t pos;
switch (mouse_mode) { switch (current_mouse_mode()) {
case MouseObject: case MouseObject:
if (!selection->regions.empty()) { if (!selection->regions.empty()) {
pos = selection->regions.start_time(); pos = selection->regions.start_time();
@ -1230,7 +1230,7 @@ Editor::cursor_to_selection_end (EditorCursor *cursor)
{ {
timepos_t pos; timepos_t pos;
switch (mouse_mode) { switch (current_mouse_mode()) {
case MouseObject: case MouseObject:
if (!selection->regions.empty()) { if (!selection->regions.empty()) {
pos = selection->regions.end_time(); pos = selection->regions.end_time();
@ -1400,7 +1400,7 @@ Editor::selected_marker_to_selection_start ()
return; return;
} }
switch (mouse_mode) { switch (current_mouse_mode()) {
case MouseObject: case MouseObject:
if (!selection->regions.empty()) { if (!selection->regions.empty()) {
pos = selection->regions.start_time(); pos = selection->regions.start_time();
@ -1435,7 +1435,7 @@ Editor::selected_marker_to_selection_end ()
return; return;
} }
switch (mouse_mode) { switch (current_mouse_mode()) {
case MouseObject: case MouseObject:
if (!selection->regions.empty()) { if (!selection->regions.empty()) {
pos = selection->regions.end_time(); pos = selection->regions.end_time();
@ -4394,7 +4394,7 @@ Editor::cut_copy (CutCopyOp op)
return; return;
} }
switch (mouse_mode) { switch (current_mouse_mode()) {
case MouseDraw: case MouseDraw:
case MouseContent: case MouseContent:
begin_reversible_command (opname + ' ' + X_("MIDI")); begin_reversible_command (opname + ' ' + X_("MIDI"));
@ -9451,11 +9451,13 @@ Editor::ripple_marks (std::shared_ptr<Playlist> target_playlist, timepos_t at, t
Editing::ZoomFocus Editing::ZoomFocus
Editor::effective_zoom_focus() const Editor::effective_zoom_focus() const
{ {
if (_zoom_focus == ZoomFocusEdit && _edit_point == EditAtMouse) { auto zf = zoom_focus();
if (zf == ZoomFocusEdit && _edit_point == EditAtMouse) {
return ZoomFocusMouse; return ZoomFocusMouse;
} }
return _zoom_focus; return zf;
} }
void void

View file

@ -1710,7 +1710,7 @@ Editor::region_selection_changed ()
/* if in TimeFX mode and there's just 1 region selected /* if in TimeFX mode and there's just 1 region selected
* (i.e. we just clicked on it), leave things as they are * (i.e. we just clicked on it), leave things as they are
*/ */
if (selection->regions.size() > 1 || mouse_mode != Editing::MouseTimeFX) { if (selection->regions.size() > 1 || current_mouse_mode() != Editing::MouseTimeFX) {
set_mouse_mode (MouseObject, false); set_mouse_mode (MouseObject, false);
} }
} }
@ -1998,7 +1998,7 @@ Editor::set_selection_from_region ()
selection->set (tvl); selection->set (tvl);
if (!get_smart_mode () || !(mouse_mode == Editing::MouseObject) ) { if (!get_smart_mode () || !(current_mouse_mode() == Editing::MouseObject) ) {
set_mouse_mode (Editing::MouseRange, false); set_mouse_mode (Editing::MouseRange, false);
} }
} }
@ -2041,7 +2041,7 @@ Editor::set_selection_from_range (Location& loc)
commit_reversible_selection_op (); commit_reversible_selection_op ();
if (!get_smart_mode () || mouse_mode != Editing::MouseObject) { if (!get_smart_mode () || current_mouse_mode() != Editing::MouseObject) {
set_mouse_mode (MouseRange, false); set_mouse_mode (MouseRange, false);
} }
} }
@ -2312,7 +2312,7 @@ Editor::select_range_between ()
return; return;
} }
if (!get_smart_mode () || mouse_mode != Editing::MouseObject) { if (!get_smart_mode () || current_mouse_mode() != Editing::MouseObject) {
set_mouse_mode (MouseRange, false); set_mouse_mode (MouseRange, false);
} }
@ -2326,16 +2326,16 @@ Editor::get_edit_op_range (timepos_t& start, timepos_t& end) const
{ {
/* if an explicit range exists, use it */ /* if an explicit range exists, use it */
if ((mouse_mode == MouseRange || get_smart_mode()) && !selection->time.empty()) { if ((current_mouse_mode() == MouseRange || get_smart_mode()) && !selection->time.empty()) {
/* we know that these are ordered */ /* we know that these are ordered */
start = selection->time.start_time(); start = selection->time.start_time();
end = selection->time.end_time(); end = selection->time.end_time();
return true; return true;
} else {
start = timepos_t ();
end = timepos_t ();
return false;
} }
start = timepos_t ();
end = timepos_t ();
return false;
} }
void void

View file

@ -75,19 +75,20 @@ Pianoroll::Pianoroll (std::string const & name, bool with_transport)
, _note_mode (Sustained) , _note_mode (Sustained)
, ignore_channel_changes (false) , ignore_channel_changes (false)
{ {
mouse_mode = Editing::MouseContent;
autoscroll_vertical_allowed = false; autoscroll_vertical_allowed = false;
build_upper_toolbar ();
build_canvas ();
build_lower_toolbar ();
load_bindings (); load_bindings ();
register_actions (); register_actions ();
build_upper_toolbar ();
build_canvas ();
build_grid_type_menu (); build_grid_type_menu ();
build_draw_midi_menus(); build_draw_midi_menus();
build_lower_toolbar ();
set_action_defaults ();
set_mouse_mode (Editing::MouseContent, true); set_mouse_mode (Editing::MouseContent, true);
} }
@ -780,7 +781,7 @@ bool
Pianoroll::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_type) Pianoroll::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_type)
{ {
NoteBase* note = nullptr; NoteBase* note = nullptr;
Editing::MouseMode mouse_mode = current_mouse_mode();
switch (item_type) { switch (item_type) {
case NoteItem: case NoteItem:
if (mouse_mode == Editing::MouseContent) { if (mouse_mode == Editing::MouseContent) {
@ -1052,7 +1053,7 @@ Pianoroll::which_mode_cursor () const
{ {
Gdk::Cursor* mode_cursor = MouseCursors::invalid_cursor (); Gdk::Cursor* mode_cursor = MouseCursors::invalid_cursor ();
switch (mouse_mode) { switch (current_mouse_mode()) {
case Editing::MouseContent: case Editing::MouseContent:
mode_cursor = _cursors->grabber; mode_cursor = _cursors->grabber;
break; break;
@ -1081,6 +1082,7 @@ Gdk::Cursor*
Pianoroll::which_canvas_cursor (ItemType type) const Pianoroll::which_canvas_cursor (ItemType type) const
{ {
Gdk::Cursor* cursor = which_mode_cursor (); Gdk::Cursor* cursor = which_mode_cursor ();
Editing::MouseMode mouse_mode = current_mouse_mode ();
if (mouse_mode == Editing::MouseContent) { if (mouse_mode == Editing::MouseContent) {
@ -1618,7 +1620,7 @@ Pianoroll::cut_copy (Editing::CutCopyOp op)
cut_buffer->clear (); cut_buffer->clear ();
} }
switch (mouse_mode) { switch (current_mouse_mode()) {
case MouseDraw: case MouseDraw:
case MouseContent: case MouseContent:
if (view) { if (view) {
@ -1781,6 +1783,7 @@ Pianoroll::map_transport_state ()
bool bool
Pianoroll::allow_trim_cursors () const Pianoroll::allow_trim_cursors () const
{ {
auto mouse_mode = current_mouse_mode ();
return mouse_mode == Editing::MouseContent || mouse_mode == Editing::MouseTimeFX; return mouse_mode == Editing::MouseContent || mouse_mode == Editing::MouseTimeFX;
} }