From 38368f4dd968d78394053a17ca1be31ea92aa49c Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Mon, 1 Dec 2025 17:55:25 -0700 Subject: [PATCH] save and restore pianoroll note mode on a per-region basis --- gtk2_ardour/editing_context.cc | 4 ++ gtk2_ardour/editing_context.h | 4 ++ gtk2_ardour/pianoroll.cc | 65 +++++++++++++++++++++---------- gtk2_ardour/pianoroll.h | 6 +-- gtk2_ardour/region_ui_settings.cc | 3 ++ gtk2_ardour/region_ui_settings.h | 3 +- 6 files changed, 61 insertions(+), 24 deletions(-) diff --git a/gtk2_ardour/editing_context.cc b/gtk2_ardour/editing_context.cc index 2afa6480c3..9b1796c787 100644 --- a/gtk2_ardour/editing_context.cc +++ b/gtk2_ardour/editing_context.cc @@ -467,6 +467,10 @@ EditingContext::register_common_actions (Bindings* common_bindings, std::string reg_sens (_common_actions, "editor-copy", _("Copy"), sigc::mem_fun (*this, &EditingContext::copy)); reg_sens (_common_actions, "editor-paste", _("Paste"), sigc::mem_fun (*this, &EditingContext::keyboard_paste)); + RadioAction::Group note_mode_group; + note_mode_actions[ARDOUR::Sustained] = ActionManager::register_radio_action (_common_actions, note_mode_group, "set-note-mode-sustained", _("Sustained"), sigc::bind (sigc::mem_fun (*this, &EditingContext::note_mode_chosen), ARDOUR::Sustained)); + note_mode_actions[ARDOUR::Percussive] = ActionManager::register_radio_action (_common_actions, note_mode_group, "set-note-mode-percussivee", _("Percussive"), sigc::bind (sigc::mem_fun (*this, &EditingContext::note_mode_chosen), ARDOUR::Percussive)); + RadioAction::Group mouse_mode_group; 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)); diff --git a/gtk2_ardour/editing_context.h b/gtk2_ardour/editing_context.h index 4a983dc1ab..81a0c56ecb 100644 --- a/gtk2_ardour/editing_context.h +++ b/gtk2_ardour/editing_context.h @@ -297,10 +297,12 @@ class EditingContext : public ARDOUR::SessionHandlePtr, public AxisViewProvider, void set_draw_length (Editing::GridType); void set_draw_velocity (int); void set_draw_channel (int); + virtual void set_note_mode (ARDOUR::NoteMode) {} Editing::GridType draw_length () const; int draw_velocity () const; int draw_channel () const; + virtual ARDOUR::NoteMode note_mode() const { return ARDOUR::Sustained; } Editing::SnapMode snap_mode () const; @@ -548,6 +550,7 @@ class EditingContext : public ARDOUR::SessionHandlePtr, public AxisViewProvider, std::map > snap_mode_actions; std::map > draw_length_actions; std::map > mouse_mode_actions; + std::map > note_mode_actions; std::map > zoom_focus_actions; std::map > draw_velocity_actions; std::map > draw_channel_actions; @@ -555,6 +558,7 @@ class EditingContext : public ARDOUR::SessionHandlePtr, public AxisViewProvider, void draw_channel_chosen (int); void draw_velocity_chosen (int); void draw_length_chosen (Editing::GridType); + virtual void note_mode_chosen (ARDOUR::NoteMode) {} sigc::signal DrawLengthChanged; sigc::signal DrawVelocityChanged; diff --git a/gtk2_ardour/pianoroll.cc b/gtk2_ardour/pianoroll.cc index f21b3b3509..0a6b0a6a88 100644 --- a/gtk2_ardour/pianoroll.cc +++ b/gtk2_ardour/pianoroll.cc @@ -74,7 +74,6 @@ Pianoroll::Pianoroll (std::string const & name, bool with_transport) , bg (nullptr) , view (nullptr) , bbt_metric (*this) - , _note_mode (Sustained) , ignore_channel_changes (false) { autoscroll_vertical_allowed = false; @@ -1587,6 +1586,40 @@ Pianoroll::automation_state_changed () } } +ARDOUR::NoteMode +Pianoroll::note_mode () const +{ + return bg->note_mode(); +} + +void +Pianoroll::note_mode_chosen (ARDOUR::NoteMode mode) +{ + EC_LOCAL_TEMPO_SCOPE; + + /* this is driven by a toggle on a radio group, and so is invoked twice, + once for the item that became inactive and once for the one that became + active. + */ + + Glib::RefPtr ract = note_mode_actions[mode]; + + if (!ract->get_active()) { + return; + } + + if (mode != bg->note_mode()) { + bg->set_note_mode (mode); + if (bg->note_mode() == Percussive) { + note_mode_button.set_active_state (Gtkmm2ext::ExplicitActive); + } else { + note_mode_button.set_active_state (Gtkmm2ext::Off); + } + } + + instant_save (); +} + void Pianoroll::note_mode_clicked () { @@ -1594,27 +1627,11 @@ Pianoroll::note_mode_clicked () assert (bg); + if (bg->note_mode() == Sustained) { - set_note_mode (Percussive); + note_mode_actions[Percussive]->set_active (true); } else { - set_note_mode (Sustained); - } -} - -void -Pianoroll::set_note_mode (NoteMode nm) -{ - EC_LOCAL_TEMPO_SCOPE; - - assert (bg); - - if (nm != bg->note_mode()) { - bg->set_note_mode (nm); - if (bg->note_mode() == Percussive) { - note_mode_button.set_active_state (Gtkmm2ext::ExplicitActive); - } else { - note_mode_button.set_active_state (Gtkmm2ext::Off); - } + note_mode_actions[Sustained]->set_active (true); } } @@ -2037,6 +2054,13 @@ Pianoroll::hide_count_in () } } +void +Pianoroll::set_from_rsu (RegionUISettings& region_ui_settings) +{ + note_mode_actions[region_ui_settings.note_mode]->set_active (true); + CueEditor::set_from_rsu (region_ui_settings); +} + void Pianoroll::instant_save () { @@ -2047,6 +2071,7 @@ Pianoroll::instant_save () region_ui_settings.channel = draw_channel(); region_ui_settings.note_min = bg->lowest_note (); region_ui_settings.note_max = bg->highest_note(); + region_ui_settings.note_mode = note_mode (); CueEditor::instant_save (); } diff --git a/gtk2_ardour/pianoroll.h b/gtk2_ardour/pianoroll.h index 4ea5600032..f51de28cd2 100644 --- a/gtk2_ardour/pianoroll.h +++ b/gtk2_ardour/pianoroll.h @@ -100,8 +100,8 @@ class Pianoroll : public CueEditor int visible_channel () const { return _visible_channel; } void note_mode_clicked(); - ARDOUR::NoteMode note_mode() const { return _note_mode; } - void set_note_mode (ARDOUR::NoteMode); + ARDOUR::NoteMode note_mode() const; + void note_mode_chosen (ARDOUR::NoteMode); void set_trigger_start (Temporal::timepos_t const &); void set_trigger_end (Temporal::timepos_t const &); @@ -213,7 +213,6 @@ class Pianoroll : public CueEditor int _visible_channel; - ARDOUR::NoteMode _note_mode; sigc::signal NoteModeChanged; void automation_state_changed (); @@ -253,4 +252,5 @@ class Pianoroll : public CueEditor void instant_save (); void parameter_changed (std::string param); + void set_from_rsu (RegionUISettings&); }; diff --git a/gtk2_ardour/region_ui_settings.cc b/gtk2_ardour/region_ui_settings.cc index 69c8909644..424e3f6534 100644 --- a/gtk2_ardour/region_ui_settings.cc +++ b/gtk2_ardour/region_ui_settings.cc @@ -40,6 +40,7 @@ RegionUISettings::RegionUISettings () , snap_mode (Editing::SnapMagnetic) , zoom_focus (ZoomFocusLeft) , mouse_mode (MouseContent) + , note_mode (ARDOUR::Sustained) , x_origin (0) , recording_length (1, 0, 0) , width (-1) @@ -65,6 +66,7 @@ RegionUISettings::get_state () const node->set_property (X_("snap-mode"), snap_mode); node->set_property (X_("zoom-focus"), zoom_focus); node->set_property (X_("mouse-mode"), mouse_mode); + node->set_property (X_("note-mode"), note_mode); node->set_property (X_("x-origin"), x_origin); node->set_property (X_("recording_length"), recording_length); @@ -95,6 +97,7 @@ RegionUISettings::set_state (XMLNode const & state, int) state.get_property (X_("snap-mode"), snap_mode); state.get_property (X_("zoom-focus"), zoom_focus); state.get_property (X_("mouse-mode"), mouse_mode); + state.get_property (X_("note-mode"), note_mode); state.get_property (X_("x-origin"), x_origin); state.get_property (X_("recording_length"), recording_length); diff --git a/gtk2_ardour/region_ui_settings.h b/gtk2_ardour/region_ui_settings.h index 3dadd4c856..dd0f3dccd0 100644 --- a/gtk2_ardour/region_ui_settings.h +++ b/gtk2_ardour/region_ui_settings.h @@ -39,13 +39,14 @@ struct RegionUISettings Editing::SnapMode snap_mode; Editing::ZoomFocus zoom_focus; Editing::MouseMode mouse_mode; + ARDOUR::NoteMode note_mode; Temporal::timepos_t x_origin; Temporal::BBT_Offset recording_length; int width; int height; int x; int y; - + /* MIDI specific */ Editing::GridType draw_length;