From d0cdd0c9db835d0d4d5a4ea9b2fb1e91344c8e90 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Thu, 18 Nov 2021 14:17:21 -0700 Subject: [PATCH] somewhat functional menu to control KeyEnforcementPolicy And yes, this should likely be global, not per track --- gtk2_ardour/midi_time_axis.cc | 64 ++++++++++++++++++++++++++++++++--- gtk2_ardour/midi_time_axis.h | 2 ++ 2 files changed, 62 insertions(+), 4 deletions(-) diff --git a/gtk2_ardour/midi_time_axis.cc b/gtk2_ardour/midi_time_axis.cc index 6605af1faa..3d3066aa9c 100644 --- a/gtk2_ardour/midi_time_axis.cc +++ b/gtk2_ardour/midi_time_axis.cc @@ -642,10 +642,7 @@ MidiTimeAxisView::append_extra_display_menu_items () items.push_back (MenuElem (_("Scale"), *build_musical_mode_menu ())); items.push_back (MenuElem (_("Tonic (Root)"), *build_musical_root_menu ())); - // items.push_back (CheckMenuElem (_("Enforce Key"))); - // Gtk::CheckMenuItem* eki = dynamic_cast (&items.back()); - // eki->set_active (midi_track ()->enforce_key ()); - // eki->signal_activate().connect (sigc::mem_fun (*this, &MidiTimeAxisView::toggle_enforce_musical_key)); + items.push_back (MenuElem (_("Key Enforcement"), *build_key_enforcement_menu())); items.push_back (MenuElem (_("Color Mode"), *build_color_mode_menu ())); @@ -1147,6 +1144,65 @@ MidiTimeAxisView::build_musical_root_menu () return root_menu; } +Gtk::Menu* +MidiTimeAxisView::build_key_enforcement_menu () +{ + using namespace Menu_Helpers; + + Menu* menu = manage (new Menu); + MenuList& items = menu->items(); + menu->set_name ("ArdourContextMenu"); + + RadioMenuItem::Group group; + CheckMenuItem* last_check_item; + RadioMenuItem* last_radio_item; + + KeyEnforcementPolicy kep = midi_track()->key_enforcment_policy(); + + items.push_back (CheckMenuElem (_("Don't show non-scale ghost notes while drawing/editing"))); + last_check_item = dynamic_cast(&items.back()); + last_check_item->set_active (kep & NoDraw); + last_check_item->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiTimeAxisView::toggle_key_enforcement_policy), NoDraw, last_check_item)); + items.push_back (CheckMenuElem (_("Don't allow mouse edits to create non-scale notes"))); + last_check_item = dynamic_cast(&items.back()); + last_check_item->set_active (kep & NoInsert); + last_check_item->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiTimeAxisView::toggle_key_enforcement_policy), NoInsert, last_check_item)); + + items.push_back (RadioMenuElem (group, _("Force note edits of non-scale notes to next lower note"))); + last_radio_item = dynamic_cast(&items.back()); + last_radio_item->set_active (kep & ForceLower); + last_radio_item->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiTimeAxisView::toggle_key_enforcement_policy), ForceLower, last_radio_item)); + items.push_back (RadioMenuElem (group, _("Force note edits of non-scale notes to next higher note"))); + last_radio_item = dynamic_cast(&items.back()); + last_radio_item->set_active (kep & ForceHigher); + last_radio_item->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiTimeAxisView::toggle_key_enforcement_policy), ForceHigher, last_radio_item)); + items.push_back (RadioMenuElem (group, _("Force note edits of non-scale notes to nearest note"))); + last_radio_item = dynamic_cast(&items.back()); + last_radio_item->set_active (kep & ForceNearest); + last_radio_item->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiTimeAxisView::toggle_key_enforcement_policy), ForceNearest, last_radio_item)); + return menu; +} + +void +MidiTimeAxisView::toggle_key_enforcement_policy (KeyEnforcementPolicy kepb, CheckMenuItem* item) +{ + KeyEnforcementPolicy kep = midi_track()->key_enforcment_policy(); + + /* Some of the menu items that trigger this are radio menu items, and + this method will be called when they go inactive. We want to ignore + these calls. + */ + + if (!item->get_active()) { + return; + } + if (kep & kepb) { + midi_track()->set_key_enforcement_policy (KeyEnforcementPolicy (kep & ~kepb)); + } else { + midi_track()->set_key_enforcement_policy (KeyEnforcementPolicy (kep | kepb)); + } +} + void MidiTimeAxisView::set_musical_root (int r) { diff --git a/gtk2_ardour/midi_time_axis.h b/gtk2_ardour/midi_time_axis.h index aea83bb286..91a4a5c1b7 100644 --- a/gtk2_ardour/midi_time_axis.h +++ b/gtk2_ardour/midi_time_axis.h @@ -136,7 +136,9 @@ private: Gtk::Menu* build_color_mode_menu(); Gtk::Menu* build_musical_mode_menu (); Gtk::Menu* build_musical_root_menu (); + Gtk::Menu* build_key_enforcement_menu (); + void toggle_key_enforcement_policy (ARDOUR::KeyEnforcementPolicy, Gtk::CheckMenuItem*); void set_musical_mode (MusicalMode::Type); void set_musical_root (int note); void set_note_mode (ARDOUR::NoteMode mode, bool apply_to_selection = false);