mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-06 14:54:56 +01:00
add alt-i as a binding in both the editor and mixer windows to toggle the state of MIDI input on the selected track(s); in the mixer this will also operate on the strip under the mouse. fixes #4838
git-svn-id: svn://localhost/ardour2/branches/3.0@13475 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
cf55921aea
commit
3fa84d0caa
14 changed files with 125 additions and 50 deletions
|
|
@ -11,6 +11,7 @@
|
||||||
<accelerator action='track-solo-toggle'/>
|
<accelerator action='track-solo-toggle'/>
|
||||||
<accelerator action='track-mute-toggle'/>
|
<accelerator action='track-mute-toggle'/>
|
||||||
<accelerator action='toggle-edit-mode'/>
|
<accelerator action='toggle-edit-mode'/>
|
||||||
|
<accelerator action='toggle-midi-input-active'/>
|
||||||
|
|
||||||
<menubar name='Main' action='MainMenu'>
|
<menubar name='Main' action='MainMenu'>
|
||||||
<menu name='Session' action='Session'>
|
<menu name='Session' action='Session'>
|
||||||
|
|
|
||||||
|
|
@ -419,7 +419,7 @@ ARDOUR_UI::setup_transport ()
|
||||||
auto_box->pack_start (auto_return_button, false, false);
|
auto_box->pack_start (auto_return_button, false, false);
|
||||||
|
|
||||||
transport_tearoff_hbox.pack_start (*auto_box, false, false);
|
transport_tearoff_hbox.pack_start (*auto_box, false, false);
|
||||||
transport_tearoff_hbox.pack_start (*clock_box, false, false);
|
transport_tearoff_hbox.pack_start (*clock_box, true, true);
|
||||||
|
|
||||||
time_info_box = manage (new TimeInfoBox);
|
time_info_box = manage (new TimeInfoBox);
|
||||||
transport_tearoff_hbox.pack_start (*time_info_box, false, false);
|
transport_tearoff_hbox.pack_start (*time_info_box, false, false);
|
||||||
|
|
|
||||||
|
|
@ -1247,6 +1247,8 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
|
||||||
boost::shared_ptr<ARDOUR::AudioTrack> get_nth_selected_audio_track (int nth) const;
|
boost::shared_ptr<ARDOUR::AudioTrack> get_nth_selected_audio_track (int nth) const;
|
||||||
boost::shared_ptr<ARDOUR::MidiTrack> get_nth_selected_midi_track (int nth) const;
|
boost::shared_ptr<ARDOUR::MidiTrack> get_nth_selected_midi_track (int nth) const;
|
||||||
|
|
||||||
|
void toggle_midi_input_active (bool flip_others);
|
||||||
|
|
||||||
ARDOUR::InterThreadInfo* current_interthread_info;
|
ARDOUR::InterThreadInfo* current_interthread_info;
|
||||||
|
|
||||||
AnalysisWindow* analysis_window;
|
AnalysisWindow* analysis_window;
|
||||||
|
|
|
||||||
|
|
@ -623,6 +623,9 @@ Editor::register_actions ()
|
||||||
Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
|
Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
|
||||||
tact->set_active (true);
|
tact->set_active (true);
|
||||||
|
|
||||||
|
ActionManager::register_action (editor_actions, X_("toggle-midi-input-active"), _("Toggle MIDI Input Active for Editor-Selected Tracks/Busses"),
|
||||||
|
sigc::bind (sigc::mem_fun (*this, &Editor::toggle_midi_input_active), false));
|
||||||
|
|
||||||
ActionManager::add_action_group (rl_actions);
|
ActionManager::add_action_group (rl_actions);
|
||||||
ActionManager::add_action_group (ruler_actions);
|
ActionManager::add_action_group (ruler_actions);
|
||||||
ActionManager::add_action_group (zoom_actions);
|
ActionManager::add_action_group (zoom_actions);
|
||||||
|
|
|
||||||
|
|
@ -6828,3 +6828,26 @@ Editor::uncombine_regions ()
|
||||||
commit_reversible_command ();
|
commit_reversible_command ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Editor::toggle_midi_input_active (bool flip_others)
|
||||||
|
{
|
||||||
|
bool onoff;
|
||||||
|
boost::shared_ptr<RouteList> rl (new RouteList);
|
||||||
|
|
||||||
|
for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
|
||||||
|
RouteTimeAxisView *rtav = dynamic_cast<RouteTimeAxisView *>(*i);
|
||||||
|
|
||||||
|
if (!rtav) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::shared_ptr<MidiTrack> mt = rtav->midi_track();
|
||||||
|
|
||||||
|
if (mt) {
|
||||||
|
rl->push_back (rtav->route());
|
||||||
|
onoff = !mt->input_active();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_session->set_exclusive_input_active (rl, onoff, flip_others);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
<Press>
|
<Press>
|
||||||
<Binding key="s" action="Mixer/solo"/>
|
<Binding key="s" action="Mixer/solo"/>
|
||||||
<Binding key="m" action="Mixer/mute"/>
|
<Binding key="m" action="Mixer/mute"/>
|
||||||
|
<Binding key="Secondary-i" action="Mixer/toggle-midi-input-active"/>
|
||||||
<Binding key="r" action="Mixer/recenable"/>
|
<Binding key="r" action="Mixer/recenable"/>
|
||||||
<Binding key="0" action="Mixer/unity-gain"/>
|
<Binding key="0" action="Mixer/unity-gain"/>
|
||||||
<Binding key="Up" action="Mixer/increment-gain"/>
|
<Binding key="Up" action="Mixer/increment-gain"/>
|
||||||
|
|
|
||||||
|
|
@ -71,6 +71,9 @@ MixerActor::register_actions ()
|
||||||
|
|
||||||
myactions.register_action ("Mixer", "scroll-left", _("Scroll Mixer Window to the left"), sigc::mem_fun (*this, &MixerActor::scroll_left));
|
myactions.register_action ("Mixer", "scroll-left", _("Scroll Mixer Window to the left"), sigc::mem_fun (*this, &MixerActor::scroll_left));
|
||||||
myactions.register_action ("Mixer", "scroll-right", _("Scroll Mixer Window to the left"), sigc::mem_fun (*this, &MixerActor::scroll_right));
|
myactions.register_action ("Mixer", "scroll-right", _("Scroll Mixer Window to the left"), sigc::mem_fun (*this, &MixerActor::scroll_right));
|
||||||
|
|
||||||
|
myactions.register_action ("Mixer", "toggle-midi-input-active", _("Toggle MIDI Input Active for Mixer-Selected Tracks/Busses"),
|
||||||
|
sigc::bind (sigc::mem_fun (*this, &MixerActor::toggle_midi_input_active), false));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -261,3 +264,4 @@ MixerActor::ab_plugins ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -63,10 +63,14 @@ class MixerActor : virtual public sigc::trackable
|
||||||
void toggle_processors ();
|
void toggle_processors ();
|
||||||
void ab_plugins ();
|
void ab_plugins ();
|
||||||
|
|
||||||
|
/* these actions need access to a Session, do defer to
|
||||||
|
a derived class
|
||||||
|
*/
|
||||||
|
virtual void toggle_midi_input_active (bool flip_others) = 0;
|
||||||
|
|
||||||
/* these actions don't apply to the selection, so defer to
|
/* these actions don't apply to the selection, so defer to
|
||||||
a derived class.
|
a derived class.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
virtual void scroll_left () {}
|
virtual void scroll_left () {}
|
||||||
virtual void scroll_right () {}
|
virtual void scroll_right () {}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1915,22 +1915,12 @@ MixerStrip::input_active_button_release (GdkEventButton* ev)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mt->input_active()) {
|
boost::shared_ptr<RouteList> rl (new RouteList);
|
||||||
if (Keyboard::modifier_state_contains (ev->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier|Keyboard::SecondaryModifier))) {
|
|
||||||
/* turn all other tracks using this input off */
|
|
||||||
_session->set_exclusive_input_active (mt, false);
|
|
||||||
} else {
|
|
||||||
mt->set_input_active (false);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
rl->push_back (route());
|
||||||
if (Keyboard::modifier_state_contains (ev->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier|Keyboard::SecondaryModifier))) {
|
|
||||||
/* turn all other tracks using this input on */
|
_session->set_exclusive_input_active (rl, !mt->input_active(),
|
||||||
_session->set_exclusive_input_active (mt, true);
|
Keyboard::modifier_state_contains (ev->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier|Keyboard::SecondaryModifier)));
|
||||||
} else {
|
|
||||||
mt->set_input_active (true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@
|
||||||
#include <gtkmm2ext/window_title.h>
|
#include <gtkmm2ext/window_title.h>
|
||||||
|
|
||||||
#include "ardour/debug.h"
|
#include "ardour/debug.h"
|
||||||
|
#include "ardour/midi_track.h"
|
||||||
#include "ardour/plugin_manager.h"
|
#include "ardour/plugin_manager.h"
|
||||||
#include "ardour/route_group.h"
|
#include "ardour/route_group.h"
|
||||||
#include "ardour/session.h"
|
#include "ardour/session.h"
|
||||||
|
|
@ -1888,7 +1889,7 @@ Mixer_UI::set_route_targets_for_operation ()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* try to get mixer strip at mouse */
|
/* nothing selected ... try to get mixer strip at mouse */
|
||||||
|
|
||||||
int x, y;
|
int x, y;
|
||||||
get_pointer (x, y);
|
get_pointer (x, y);
|
||||||
|
|
@ -1908,3 +1909,23 @@ Mixer_UI::monitor_section_going_away ()
|
||||||
_monitor_section->set_session (0);
|
_monitor_section->set_session (0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Mixer_UI::toggle_midi_input_active (bool flip_others)
|
||||||
|
{
|
||||||
|
boost::shared_ptr<RouteList> rl (new RouteList);
|
||||||
|
bool onoff;
|
||||||
|
|
||||||
|
set_route_targets_for_operation ();
|
||||||
|
|
||||||
|
for (RouteUISelection::iterator r = _route_targets.begin(); r != _route_targets.end(); ++r) {
|
||||||
|
boost::shared_ptr<MidiTrack> mt = (*r)->midi_track();
|
||||||
|
|
||||||
|
if (mt) {
|
||||||
|
rl->push_back ((*r)->route());
|
||||||
|
onoff = !mt->input_active();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_session->set_exclusive_input_active (rl, onoff, flip_others);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -129,6 +129,7 @@ class Mixer_UI : public Gtk::Window, public PBD::ScopedConnectionList, public AR
|
||||||
bool strip_scroller_button_release (GdkEventButton*);
|
bool strip_scroller_button_release (GdkEventButton*);
|
||||||
void scroll_left ();
|
void scroll_left ();
|
||||||
void scroll_right ();
|
void scroll_right ();
|
||||||
|
void toggle_midi_input_active (bool flip_others);
|
||||||
|
|
||||||
void add_strips (ARDOUR::RouteList&);
|
void add_strips (ARDOUR::RouteList&);
|
||||||
void remove_strip (MixerStrip *);
|
void remove_strip (MixerStrip *);
|
||||||
|
|
|
||||||
|
|
@ -157,6 +157,7 @@ This mode provides many different operations on both regions and control points,
|
||||||
@eep|Region/insert-region-from-region-list|i|insert from region list
|
@eep|Region/insert-region-from-region-list|i|insert from region list
|
||||||
@select|Editor/invert-selection|<@TERTIARY@>i|invert selection
|
@select|Editor/invert-selection|<@TERTIARY@>i|invert selection
|
||||||
@sess|Editor/addExistingAudioFiles|<@PRIMARY@>i|import audio files
|
@sess|Editor/addExistingAudioFiles|<@PRIMARY@>i|import audio files
|
||||||
|
@sess|Editor/toggle-midi-input-active|<@SECONDARY@>i|toggle selected track(s) MIDI input
|
||||||
@mmode|MouseMode/set-mouse-mode-object|o|object mode
|
@mmode|MouseMode/set-mouse-mode-object|o|object mode
|
||||||
@sess|Main/Open|<@PRIMARY@>o|open an existing session
|
@sess|Main/Open|<@PRIMARY@>o|open an existing session
|
||||||
@sess|Main/Recent|<@PRIMARY@><@TERTIARY@>o|open a recent session
|
@sess|Main/Recent|<@PRIMARY@><@TERTIARY@>o|open a recent session
|
||||||
|
|
|
||||||
|
|
@ -251,7 +251,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
|
||||||
boost::shared_ptr<Route> route_by_id (PBD::ID);
|
boost::shared_ptr<Route> route_by_id (PBD::ID);
|
||||||
boost::shared_ptr<Route> route_by_remote_id (uint32_t id);
|
boost::shared_ptr<Route> route_by_remote_id (uint32_t id);
|
||||||
boost::shared_ptr<Track> track_by_diskstream_id (PBD::ID);
|
boost::shared_ptr<Track> track_by_diskstream_id (PBD::ID);
|
||||||
void routes_using_input_from (const std::string& str, RouteList& rl);
|
void routes_using_input_from (const std::string& str, RouteList& rl);
|
||||||
|
|
||||||
bool route_name_unique (std::string) const;
|
bool route_name_unique (std::string) const;
|
||||||
bool route_name_internal (std::string) const;
|
bool route_name_internal (std::string) const;
|
||||||
|
|
@ -616,8 +616,8 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
|
||||||
void set_listen (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
|
void set_listen (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
|
||||||
void set_record_enabled (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
|
void set_record_enabled (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
|
||||||
void set_solo_isolated (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
|
void set_solo_isolated (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
|
||||||
void set_exclusive_input_active (boost::shared_ptr<Route> rt, bool others_on);
|
|
||||||
void set_monitoring (boost::shared_ptr<RouteList>, MonitorChoice, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
|
void set_monitoring (boost::shared_ptr<RouteList>, MonitorChoice, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
|
||||||
|
void set_exclusive_input_active (boost::shared_ptr<RouteList> rt, bool onoff, bool flip_others=false);
|
||||||
|
|
||||||
PBD::Signal1<void,bool> SoloActive;
|
PBD::Signal1<void,bool> SoloActive;
|
||||||
PBD::Signal0<void> SoloChanged;
|
PBD::Signal0<void> SoloChanged;
|
||||||
|
|
|
||||||
|
|
@ -2686,44 +2686,68 @@ Session::io_name_is_legal (const std::string& name)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Session::set_exclusive_input_active (boost::shared_ptr<Route> rt, bool /*others_on*/)
|
Session::set_exclusive_input_active (boost::shared_ptr<RouteList> rl, bool onoff, bool flip_others)
|
||||||
{
|
{
|
||||||
RouteList rl;
|
RouteList rl2;
|
||||||
vector<string> connections;
|
vector<string> connections;
|
||||||
|
|
||||||
PortSet& ps (rt->input()->ports());
|
/* if we are passed only a single route and we're not told to turn
|
||||||
|
* others off, then just do the simple thing.
|
||||||
|
*/
|
||||||
|
|
||||||
for (PortSet::iterator p = ps.begin(); p != ps.end(); ++p) {
|
if (flip_others == false && rl->size() == 1) {
|
||||||
p->get_connections (connections);
|
boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (rl->front());
|
||||||
}
|
if (mt) {
|
||||||
|
mt->set_input_active (onoff);
|
||||||
for (vector<string>::iterator s = connections.begin(); s != connections.end(); ++s) {
|
return;
|
||||||
routes_using_input_from (*s, rl);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* scan all relevant routes to see if others are on or off */
|
|
||||||
|
|
||||||
bool others_are_already_on = false;
|
|
||||||
|
|
||||||
for (RouteList::iterator r = rl.begin(); r != rl.end(); ++r) {
|
|
||||||
if ((*r) != rt) {
|
|
||||||
boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (*r);
|
|
||||||
if (mt) {
|
|
||||||
if (mt->input_active()) {
|
|
||||||
others_are_already_on = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* globally reverse other routes */
|
for (RouteList::iterator rt = rl->begin(); rt != rl->end(); ++rt) {
|
||||||
|
|
||||||
|
PortSet& ps ((*rt)->input()->ports());
|
||||||
|
|
||||||
|
for (PortSet::iterator p = ps.begin(); p != ps.end(); ++p) {
|
||||||
|
p->get_connections (connections);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (vector<string>::iterator s = connections.begin(); s != connections.end(); ++s) {
|
||||||
|
routes_using_input_from (*s, rl2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* scan all relevant routes to see if others are on or off */
|
||||||
|
|
||||||
|
bool others_are_already_on = false;
|
||||||
|
|
||||||
|
for (RouteList::iterator r = rl2.begin(); r != rl2.end(); ++r) {
|
||||||
|
|
||||||
for (RouteList::iterator r = rl.begin(); r != rl.end(); ++r) {
|
|
||||||
if ((*r) != rt) {
|
|
||||||
boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (*r);
|
boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (*r);
|
||||||
if (mt) {
|
|
||||||
mt->set_input_active (!others_are_already_on);
|
if (!mt) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((*r) != (*rt)) {
|
||||||
|
if (mt->input_active()) {
|
||||||
|
others_are_already_on = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* this one needs changing */
|
||||||
|
mt->set_input_active (onoff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flip_others) {
|
||||||
|
|
||||||
|
/* globally reverse other routes */
|
||||||
|
|
||||||
|
for (RouteList::iterator r = rl2.begin(); r != rl2.end(); ++r) {
|
||||||
|
if ((*r) != (*rt)) {
|
||||||
|
boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (*r);
|
||||||
|
if (mt) {
|
||||||
|
mt->set_input_active (!others_are_already_on);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2732,7 +2756,7 @@ Session::set_exclusive_input_active (boost::shared_ptr<Route> rt, bool /*others_
|
||||||
void
|
void
|
||||||
Session::routes_using_input_from (const string& str, RouteList& rl)
|
Session::routes_using_input_from (const string& str, RouteList& rl)
|
||||||
{
|
{
|
||||||
boost::shared_ptr<RouteList> r = routes.reader ();
|
boost::shared_ptr<RouteList> r = routes.reader();
|
||||||
|
|
||||||
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
|
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
|
||||||
if ((*i)->input()->connected_to (str)) {
|
if ((*i)->input()->connected_to (str)) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue