some deep tweaking to get MIDI channel control into nearly done shape for 3.1
This commit is contained in:
parent
613678233a
commit
f1ce235b6b
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Copyright (C) 2008 Paul Davis
|
||||
Author: Hans Baier
|
||||
Copyright (C) 2008-2013 Paul Davis
|
||||
Original Author: Hans Baier
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -30,6 +30,7 @@
|
|||
|
||||
#include "gtkmm2ext/gtk_ui.h"
|
||||
#include "gtkmm2ext/gui_thread.h"
|
||||
#include "gtkmm2ext/utils.h"
|
||||
|
||||
#include "ardour/midi_track.h"
|
||||
|
||||
|
@ -326,16 +327,25 @@ MidiMultipleChannelSelector::invert_selection(void)
|
|||
/*-----------------------------------------*/
|
||||
|
||||
MidiChannelSelectorWindow::MidiChannelSelectorWindow (boost::shared_ptr<MidiTrack> mt)
|
||||
: ArdourWindow (string_compose (_("MIDI Channel Control for %1"), mt->name()))
|
||||
: ArdourWindow (_("MIDI Channel Control"))
|
||||
, track (mt)
|
||||
, playback_all_button (playback_button_group, _("Playback all channels"))
|
||||
, playback_filter_button (playback_button_group, _("Play only selected channels"))
|
||||
, playback_force_button (playback_button_group, _("Use a single fixed channel for all playback"))
|
||||
, capture_all_button (capture_button_group, _("Record all channels"))
|
||||
, capture_filter_button (capture_button_group, _("Record only selected channels"))
|
||||
, capture_force_button (capture_button_group, _("Force all channels to 1 channel"))
|
||||
, last_drawn_capture_mode (AllChannels)
|
||||
, last_drawn_playback_mode (AllChannels)
|
||||
{
|
||||
build ();
|
||||
|
||||
playback_mask_changed ();
|
||||
playback_mode_changed ();
|
||||
capture_mask_changed ();
|
||||
capture_mode_changed ();
|
||||
|
||||
playback_mask_changed ();
|
||||
capture_mask_changed ();
|
||||
|
||||
track->PlaybackChannelMaskChanged.connect (*this, MISSING_INVALIDATOR, boost::bind (&MidiChannelSelectorWindow::playback_mask_changed, this), gui_context());
|
||||
track->PlaybackChannelModeChanged.connect (*this, MISSING_INVALIDATOR, boost::bind (&MidiChannelSelectorWindow::playback_mode_changed, this), gui_context());
|
||||
track->CaptureChannelMaskChanged.connect (*this, MISSING_INVALIDATOR, boost::bind (&MidiChannelSelectorWindow::capture_mask_changed, this), gui_context());
|
||||
|
@ -350,122 +360,93 @@ void
|
|||
MidiChannelSelectorWindow::build ()
|
||||
{
|
||||
VBox* vpacker;
|
||||
HBox* capture_mask;
|
||||
HBox* capture_mask_controls;
|
||||
HBox* playback_mask;
|
||||
HBox* playback_mask_controls;
|
||||
HBox* capture_controls;
|
||||
HBox* playback_controls;
|
||||
Button* b;
|
||||
ToggleButton* tb;
|
||||
Label* l;
|
||||
|
||||
vpacker = manage (new VBox);
|
||||
vpacker->set_spacing (6);
|
||||
vpacker->set_border_width (12);
|
||||
|
||||
l = manage (new Label (string_compose ("<span size=\"large\" weight=\"bold\">%1</span>", _("Capture"))));
|
||||
l = manage (new Label (string_compose (("<span size=\"larger\" weight=\"bold\">%1: %2</span>"), _("MIDI Channel Control"), track->name())));
|
||||
l->set_use_markup (true);
|
||||
l->set_alignment (0.5, 0.0);
|
||||
|
||||
vpacker->pack_start (*l, true, true);
|
||||
|
||||
l = manage (new Label (string_compose ("<span size=\"large\" weight=\"bold\">%1</span>", _("Inbound"))));
|
||||
l->set_use_markup (true);
|
||||
vpacker->pack_start (*l);
|
||||
|
||||
{
|
||||
RadioButtonGroup group;
|
||||
|
||||
capture_all_button = manage (new RadioButton (group, "Record all channels"));
|
||||
vpacker->pack_start (*capture_all_button);
|
||||
capture_all_button->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiChannelSelectorWindow::capture_mode_toggled), AllChannels));
|
||||
vpacker->pack_start (capture_all_button);
|
||||
capture_all_button.signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiChannelSelectorWindow::capture_mode_toggled), AllChannels));
|
||||
|
||||
vpacker->pack_start (capture_filter_button);
|
||||
capture_filter_button.signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiChannelSelectorWindow::capture_mode_toggled), FilterChannels));
|
||||
|
||||
vpacker->pack_start (capture_force_button);
|
||||
capture_force_button.signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiChannelSelectorWindow::capture_mode_toggled), ForceChannel));
|
||||
|
||||
capture_filter_button = manage (new RadioButton (group, "Record only selected channels"));
|
||||
vpacker->pack_start (*capture_filter_button);
|
||||
capture_filter_button->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiChannelSelectorWindow::capture_mode_toggled), FilterChannels));
|
||||
|
||||
capture_force_button = manage (new RadioButton (group, "Force all channels to a single fixed channel"));
|
||||
vpacker->pack_start (*capture_force_button);
|
||||
capture_force_button->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiChannelSelectorWindow::capture_mode_toggled), ForceChannel));
|
||||
}
|
||||
|
||||
capture_mask = manage (new HBox);
|
||||
|
||||
for (uint32_t n = 0; n < 16; ++n) {
|
||||
char buf[3];
|
||||
snprintf (buf, sizeof (buf), "%d", n+1);
|
||||
tb = manage (new ToggleButton (buf));
|
||||
Gtkmm2ext::UI::instance()->set_tip (*tb, string_compose (_("Click to toggle recording of channel %1"), n+1));
|
||||
capture_buttons.push_back (tb);
|
||||
tb->set_name (X_("MidiChannelSelectorButton"));
|
||||
capture_mask->pack_start (*tb);
|
||||
tb->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiChannelSelectorWindow::capture_channel_clicked), n));
|
||||
}
|
||||
|
||||
vpacker->pack_start (*capture_mask);
|
||||
|
||||
capture_mask_controls = manage (new HBox);
|
||||
capture_mask_controls->set_spacing (6);
|
||||
vpacker->pack_start (capture_mask_box);
|
||||
|
||||
capture_controls = manage (new HBox);
|
||||
capture_controls->set_spacing (6);
|
||||
|
||||
b = manage (new Button (_("All")));
|
||||
Gtkmm2ext::UI::instance()->set_tip (*b, _("Click to enable recording all channels"));
|
||||
capture_mask_controls->pack_start (*b);
|
||||
capture_controls->pack_start (*b);
|
||||
capture_mask_controls.push_back (b);
|
||||
b->signal_clicked().connect (sigc::mem_fun (*this, &MidiChannelSelectorWindow::fill_capture_mask));
|
||||
b = manage (new Button (_("None")));
|
||||
Gtkmm2ext::UI::instance()->set_tip (*b, _("Click to disable recording all channels"));
|
||||
capture_mask_controls->pack_start (*b);
|
||||
capture_controls->pack_start (*b);
|
||||
capture_mask_controls.push_back (b);
|
||||
b->signal_clicked().connect (sigc::mem_fun (*this, &MidiChannelSelectorWindow::zero_capture_mask));
|
||||
b = manage (new Button (_("Invert")));
|
||||
Gtkmm2ext::UI::instance()->set_tip (*b, _("Click to invert currently selected recording channels"));
|
||||
capture_mask_controls->pack_start (*b);
|
||||
capture_controls->pack_start (*b);
|
||||
capture_mask_controls.push_back (b);
|
||||
b->signal_clicked().connect (sigc::mem_fun (*this, &MidiChannelSelectorWindow::invert_capture_mask));
|
||||
|
||||
vpacker->pack_start (*capture_mask_controls);
|
||||
|
||||
playback_mask = manage (new HBox);
|
||||
vpacker->pack_start (*capture_controls);
|
||||
|
||||
l = manage (new Label (string_compose ("<span size=\"large\" weight=\"bold\">%1</span>", _("Playback"))));
|
||||
l->set_use_markup (true);
|
||||
vpacker->pack_start (*l);
|
||||
|
||||
{
|
||||
RadioButtonGroup group;
|
||||
vpacker->pack_start (playback_all_button);
|
||||
playback_all_button.signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiChannelSelectorWindow::playback_mode_toggled), AllChannels));
|
||||
|
||||
vpacker->pack_start (playback_filter_button);
|
||||
playback_filter_button.signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiChannelSelectorWindow::playback_mode_toggled), FilterChannels));
|
||||
|
||||
vpacker->pack_start (playback_force_button);
|
||||
playback_force_button.signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiChannelSelectorWindow::playback_mode_toggled), ForceChannel));
|
||||
|
||||
playback_all_button = manage (new RadioButton (group, "Playback all channels"));
|
||||
vpacker->pack_start (*playback_all_button);
|
||||
playback_all_button->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiChannelSelectorWindow::playback_mode_toggled), AllChannels));
|
||||
vpacker->pack_start (playback_mask_box);
|
||||
|
||||
playback_filter_button = manage (new RadioButton (group, "Play only selected channels"));
|
||||
vpacker->pack_start (*playback_filter_button);
|
||||
playback_filter_button->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiChannelSelectorWindow::playback_mode_toggled), FilterChannels));
|
||||
|
||||
playback_force_button = manage (new RadioButton (group, "Use a single fixed channel for all playback"));
|
||||
vpacker->pack_start (*playback_force_button);
|
||||
playback_force_button->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiChannelSelectorWindow::playback_mode_toggled), ForceChannel));
|
||||
}
|
||||
|
||||
for (uint32_t n = 0; n < 16; ++n) {
|
||||
char buf[3];
|
||||
snprintf (buf, sizeof (buf), "%d", n+1);
|
||||
tb = manage (new ToggleButton (buf));
|
||||
tb->set_name (X_("MidiChannelSelectorButton"));
|
||||
playback_buttons.push_back (tb);
|
||||
playback_mask->pack_start (*tb);
|
||||
tb->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiChannelSelectorWindow::playback_channel_clicked), n));
|
||||
}
|
||||
|
||||
vpacker->pack_start (*playback_mask);
|
||||
|
||||
playback_mask_controls = manage (new HBox);
|
||||
playback_mask_controls->set_spacing (6);
|
||||
playback_controls = manage (new HBox);
|
||||
playback_controls->set_spacing (6);
|
||||
|
||||
b = manage (new Button (_("All")));
|
||||
Gtkmm2ext::UI::instance()->set_tip (*b, _("Click to enable playback of all channels"));
|
||||
playback_mask_controls->pack_start (*b);
|
||||
playback_controls->pack_start (*b);
|
||||
playback_mask_controls.push_back (b);
|
||||
b->signal_clicked().connect (sigc::mem_fun (*this, &MidiChannelSelectorWindow::fill_playback_mask));
|
||||
b = manage (new Button (_("None")));
|
||||
Gtkmm2ext::UI::instance()->set_tip (*b, _("Click to disable playback of all channels"));
|
||||
playback_mask_controls->pack_start (*b);
|
||||
playback_controls->pack_start (*b);
|
||||
playback_mask_controls.push_back (b);
|
||||
b->signal_clicked().connect (sigc::mem_fun (*this, &MidiChannelSelectorWindow::zero_playback_mask));
|
||||
b = manage (new Button (_("Invert")));
|
||||
Gtkmm2ext::UI::instance()->set_tip (*b, _("Click to invert current selected playback channels"));
|
||||
playback_mask_controls->pack_start (*b);
|
||||
playback_controls->pack_start (*b);
|
||||
playback_mask_controls.push_back (b);
|
||||
b->signal_clicked().connect (sigc::mem_fun (*this, &MidiChannelSelectorWindow::invert_playback_mask));
|
||||
|
||||
vpacker->pack_start (*playback_mask_controls);
|
||||
vpacker->pack_start (*playback_controls);
|
||||
|
||||
add (*vpacker);
|
||||
}
|
||||
|
@ -473,52 +454,94 @@ MidiChannelSelectorWindow::build ()
|
|||
void
|
||||
MidiChannelSelectorWindow::fill_playback_mask ()
|
||||
{
|
||||
track->set_playback_channel_mask (0xffff);
|
||||
if (track->get_playback_channel_mode() == FilterChannels) {
|
||||
track->set_playback_channel_mask (0xffff);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MidiChannelSelectorWindow::zero_playback_mask ()
|
||||
{
|
||||
track->set_playback_channel_mask (0);
|
||||
if (track->get_playback_channel_mode() == FilterChannels) {
|
||||
track->set_playback_channel_mask (0);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MidiChannelSelectorWindow::invert_playback_mask ()
|
||||
{
|
||||
track->set_playback_channel_mask (~track->get_playback_channel_mask());
|
||||
if (track->get_playback_channel_mode() == FilterChannels) {
|
||||
track->set_playback_channel_mask (~track->get_playback_channel_mask());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MidiChannelSelectorWindow::fill_capture_mask ()
|
||||
{
|
||||
track->set_capture_channel_mask (0xffff);
|
||||
if (track->get_capture_channel_mode() == FilterChannels) {
|
||||
track->set_capture_channel_mask (0xffff);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MidiChannelSelectorWindow::zero_capture_mask ()
|
||||
{
|
||||
track->set_capture_channel_mask (0);
|
||||
if (track->get_capture_channel_mode() == FilterChannels) {
|
||||
track->set_capture_channel_mask (0);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MidiChannelSelectorWindow::invert_capture_mask ()
|
||||
{
|
||||
track->set_capture_channel_mask (~track->get_capture_channel_mask());
|
||||
if (track->get_capture_channel_mode() == FilterChannels) {
|
||||
track->set_capture_channel_mask (~track->get_capture_channel_mask());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MidiChannelSelectorWindow::set_playback_selected_channels (uint16_t mask)
|
||||
{
|
||||
for (uint16_t i = 0; i < 16; i++) {
|
||||
playback_buttons[i]->set_active ((1<<i) & mask);
|
||||
switch (track->get_playback_channel_mode()) {
|
||||
case AllChannels:
|
||||
/* they are insensitive, so we don't care */
|
||||
break;
|
||||
|
||||
case FilterChannels:
|
||||
for (uint16_t i = 0; i < 16; i++) {
|
||||
playback_buttons[i]->set_active ((1<<i) & mask);
|
||||
}
|
||||
break;
|
||||
|
||||
case ForceChannel:
|
||||
/* only set the lowest set channel in the mask as active */
|
||||
for (uint16_t i = 0; i < 16; i++) {
|
||||
playback_buttons[i]->set_active (i == (ffs (mask) - 1));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MidiChannelSelectorWindow::set_capture_selected_channels (uint16_t mask)
|
||||
{
|
||||
for (uint16_t i = 0; i < 16; i++) {
|
||||
capture_buttons[i]->set_active ((1<<i) & mask);
|
||||
switch (track->get_capture_channel_mode()) {
|
||||
case AllChannels:
|
||||
/* they are insensitive, so we don't care */
|
||||
break;
|
||||
|
||||
case FilterChannels:
|
||||
for (uint16_t i = 0; i < 16; i++) {
|
||||
capture_buttons[i]->set_active ((1<<i) & mask);
|
||||
}
|
||||
break;
|
||||
|
||||
case ForceChannel:
|
||||
/* only set the lowest set channel in the mask as active */
|
||||
for (uint16_t i = 0; i < 16; i++) {
|
||||
capture_buttons[i]->set_active (i == (ffs (mask) - 1));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -537,42 +560,217 @@ MidiChannelSelectorWindow::capture_mask_changed ()
|
|||
void
|
||||
MidiChannelSelectorWindow::playback_mode_changed ()
|
||||
{
|
||||
switch (track->get_playback_channel_mode()) {
|
||||
uint32_t first_channel = 0;
|
||||
ChannelMode mode = track->get_playback_channel_mode();
|
||||
|
||||
switch (mode) {
|
||||
case AllChannels:
|
||||
playback_all_button->set_active ();
|
||||
if (last_drawn_playback_mode == ForceChannel) {
|
||||
/* force mode used radio buttons. not what we want,
|
||||
* though one could argue that we want no buttons
|
||||
* at since they are insensitive
|
||||
*/
|
||||
playback_buttons.clear ();
|
||||
}
|
||||
for (vector<Widget*>::iterator i = playback_mask_controls.begin(); i != playback_mask_controls.end(); ++i) {
|
||||
(*i)->set_sensitive (false);
|
||||
}
|
||||
playback_all_button.set_active ();
|
||||
break;
|
||||
|
||||
case FilterChannels:
|
||||
playback_filter_button->set_active ();
|
||||
if (last_drawn_playback_mode == ForceChannel) {
|
||||
playback_buttons.clear ();
|
||||
} else if (last_drawn_playback_mode == AllChannels) {
|
||||
for (vector<ToggleButton*>::iterator i = playback_buttons.begin(); i != playback_buttons.end(); ++i) {
|
||||
(*i)->set_sensitive (true);
|
||||
}
|
||||
}
|
||||
for (vector<Widget*>::iterator i = playback_mask_controls.begin(); i != playback_mask_controls.end(); ++i) {
|
||||
(*i)->set_sensitive (true);
|
||||
}
|
||||
playback_filter_button.set_active ();
|
||||
break;
|
||||
|
||||
case ForceChannel:
|
||||
playback_force_button->set_active ();
|
||||
if (last_drawn_playback_mode == AllChannels || last_drawn_playback_mode == FilterChannels) {
|
||||
playback_buttons.clear ();
|
||||
first_channel = ffs (track->get_playback_channel_mask()) - 1;
|
||||
}
|
||||
for (vector<Widget*>::iterator i = playback_mask_controls.begin(); i != playback_mask_controls.end(); ++i) {
|
||||
(*i)->set_sensitive (false);
|
||||
}
|
||||
playback_force_button.set_active ();
|
||||
break;
|
||||
}
|
||||
|
||||
if (playback_buttons.empty()) {
|
||||
|
||||
Gtkmm2ext::container_clear (playback_mask_box);
|
||||
|
||||
ToggleButton* tb;
|
||||
RadioButtonGroup group;
|
||||
|
||||
for (uint32_t n = 0; n < 16; ++n) {
|
||||
char buf[3];
|
||||
snprintf (buf, sizeof (buf), "%d", n+1);
|
||||
|
||||
switch (mode) {
|
||||
case AllChannels:
|
||||
case FilterChannels:
|
||||
tb = manage (new ToggleButton (buf));
|
||||
Gtkmm2ext::UI::instance()->set_tip (*tb, string_compose (_("Click to toggle playback of channel %1"), n+1));
|
||||
break;
|
||||
case ForceChannel:
|
||||
tb = manage (new RadioButton (group, buf));
|
||||
tb->property_draw_indicator() = false;
|
||||
if (n == first_channel) {
|
||||
tb->set_active (true);
|
||||
}
|
||||
Gtkmm2ext::UI::instance()->set_tip (*tb, string_compose (_("Click to force all MIDI channel messages to channel %1"), n+1));
|
||||
break;
|
||||
}
|
||||
playback_buttons.push_back (tb);
|
||||
tb->set_name (X_("MidiChannelSelectorButton"));
|
||||
playback_mask_box.pack_start (*tb);
|
||||
tb->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiChannelSelectorWindow::playback_channel_clicked), n));
|
||||
tb->show ();
|
||||
|
||||
if (mode == AllChannels) {
|
||||
tb->set_sensitive (false);
|
||||
}
|
||||
}
|
||||
|
||||
if (mode != ForceChannel) {
|
||||
set_playback_selected_channels (track->get_playback_channel_mask());
|
||||
}
|
||||
}
|
||||
|
||||
if (mode == AllChannels) {
|
||||
for (vector<ToggleButton*>::iterator i = playback_buttons.begin(); i != playback_buttons.end(); ++i) {
|
||||
(*i)->set_sensitive (false);
|
||||
}
|
||||
}
|
||||
|
||||
last_drawn_playback_mode = mode;
|
||||
}
|
||||
|
||||
void
|
||||
MidiChannelSelectorWindow::capture_mode_changed ()
|
||||
{
|
||||
switch (track->get_capture_channel_mode()) {
|
||||
uint32_t first_channel = 0;
|
||||
ChannelMode mode = track->get_capture_channel_mode();
|
||||
|
||||
switch (mode) {
|
||||
case AllChannels:
|
||||
capture_all_button->set_active ();
|
||||
if (last_drawn_capture_mode == ForceChannel) {
|
||||
/* force mode used radio buttons. not what we want,
|
||||
* though one could argue that we want no buttons
|
||||
* at since they are insensitive
|
||||
*/
|
||||
capture_buttons.clear ();
|
||||
}
|
||||
for (vector<Widget*>::iterator i = capture_mask_controls.begin(); i != capture_mask_controls.end(); ++i) {
|
||||
(*i)->set_sensitive (false);
|
||||
}
|
||||
capture_all_button.set_active ();
|
||||
break;
|
||||
|
||||
case FilterChannels:
|
||||
capture_filter_button->set_active ();
|
||||
if (last_drawn_capture_mode == ForceChannel) {
|
||||
capture_buttons.clear ();
|
||||
} else if (last_drawn_capture_mode == AllChannels) {
|
||||
for (vector<ToggleButton*>::iterator i = capture_buttons.begin(); i != capture_buttons.end(); ++i) {
|
||||
(*i)->set_sensitive (true);
|
||||
}
|
||||
}
|
||||
for (vector<Widget*>::iterator i = capture_mask_controls.begin(); i != capture_mask_controls.end(); ++i) {
|
||||
(*i)->set_sensitive (true);
|
||||
}
|
||||
capture_filter_button.set_active ();
|
||||
break;
|
||||
|
||||
case ForceChannel:
|
||||
capture_force_button->set_active ();
|
||||
if (last_drawn_capture_mode == AllChannels || last_drawn_capture_mode == FilterChannels) {
|
||||
capture_buttons.clear ();
|
||||
first_channel = ffs (track->get_capture_channel_mask()) - 1;
|
||||
}
|
||||
for (vector<Widget*>::iterator i = capture_mask_controls.begin(); i != capture_mask_controls.end(); ++i) {
|
||||
(*i)->set_sensitive (false);
|
||||
}
|
||||
capture_force_button.set_active ();
|
||||
break;
|
||||
}
|
||||
|
||||
if (capture_buttons.empty()) {
|
||||
|
||||
Gtkmm2ext::container_clear (capture_mask_box);
|
||||
|
||||
ToggleButton* tb;
|
||||
RadioButtonGroup group;
|
||||
|
||||
for (uint32_t n = 0; n < 16; ++n) {
|
||||
char buf[3];
|
||||
snprintf (buf, sizeof (buf), "%d", n+1);
|
||||
|
||||
switch (mode) {
|
||||
case AllChannels:
|
||||
case FilterChannels:
|
||||
tb = manage (new ToggleButton (buf));
|
||||
Gtkmm2ext::UI::instance()->set_tip (*tb, string_compose (_("Click to toggle recording of channel %1"), n+1));
|
||||
break;
|
||||
case ForceChannel:
|
||||
tb = manage (new RadioButton (group, buf));
|
||||
tb->property_draw_indicator() = false;
|
||||
if (n == first_channel) {
|
||||
tb->set_active (true);
|
||||
}
|
||||
Gtkmm2ext::UI::instance()->set_tip (*tb, string_compose (_("Click to force all recorded channels to %1"), n+1));
|
||||
break;
|
||||
}
|
||||
capture_buttons.push_back (tb);
|
||||
tb->set_name (X_("MidiChannelSelectorButton"));
|
||||
capture_mask_box.pack_start (*tb);
|
||||
tb->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiChannelSelectorWindow::capture_channel_clicked), n));
|
||||
tb->show ();
|
||||
|
||||
if (mode == AllChannels) {
|
||||
tb->set_sensitive (false);
|
||||
}
|
||||
}
|
||||
|
||||
if (mode != ForceChannel) {
|
||||
set_capture_selected_channels (track->get_capture_channel_mask());
|
||||
}
|
||||
}
|
||||
|
||||
if (mode == AllChannels) {
|
||||
for (vector<ToggleButton*>::iterator i = capture_buttons.begin(); i != capture_buttons.end(); ++i) {
|
||||
(*i)->set_sensitive (false);
|
||||
}
|
||||
}
|
||||
|
||||
last_drawn_capture_mode = mode;
|
||||
}
|
||||
|
||||
void
|
||||
MidiChannelSelectorWindow::playback_channel_clicked (uint16_t n)
|
||||
{
|
||||
if (playback_buttons[n]->get_active()) {
|
||||
track->set_playback_channel_mask (track->get_playback_channel_mask() | (1<<n));
|
||||
switch (track->get_playback_channel_mode()) {
|
||||
case AllChannels:
|
||||
break;
|
||||
case FilterChannels:
|
||||
track->set_playback_channel_mask (track->get_playback_channel_mask() | (1<<n));
|
||||
break;
|
||||
case ForceChannel:
|
||||
track->set_playback_channel_mask (1<<n);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
track->set_playback_channel_mask (track->get_playback_channel_mask() & ~(1<<n));
|
||||
if (track->get_playback_channel_mode() == FilterChannels) {
|
||||
track->set_playback_channel_mask (track->get_playback_channel_mask() & ~(1<<n));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -580,9 +778,20 @@ void
|
|||
MidiChannelSelectorWindow::capture_channel_clicked (uint16_t n)
|
||||
{
|
||||
if (capture_buttons[n]->get_active()) {
|
||||
track->set_capture_channel_mask (track->get_capture_channel_mask() | (1<<n));
|
||||
switch (track->get_capture_channel_mode()) {
|
||||
case AllChannels:
|
||||
break;
|
||||
case FilterChannels:
|
||||
track->set_capture_channel_mask (track->get_capture_channel_mask() | (1<<n));
|
||||
break;
|
||||
case ForceChannel:
|
||||
track->set_capture_channel_mask (1<<n);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
track->set_capture_channel_mask (track->get_capture_channel_mask() & ~(1<<n));
|
||||
if (track->get_capture_channel_mode() == FilterChannels) {
|
||||
track->set_capture_channel_mask (track->get_capture_channel_mask() & ~(1<<n));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -593,27 +802,25 @@ MidiChannelSelectorWindow::capture_mode_toggled (ChannelMode mode)
|
|||
is for the button/mode that has been turned off, and the second is for the
|
||||
button/mode that has been turned on.
|
||||
|
||||
so we have to check the button state to know what to do.
|
||||
so we take action only if the button is active (i.e it is the one
|
||||
just clicked on)
|
||||
*/
|
||||
|
||||
|
||||
switch (mode) {
|
||||
case AllChannels:
|
||||
if (!capture_all_button->get_active()) {
|
||||
return;
|
||||
if (capture_all_button.get_active()) {
|
||||
track->set_capture_channel_mode (AllChannels, track->get_capture_channel_mask());
|
||||
}
|
||||
track->set_capture_channel_mode (AllChannels, track->get_capture_channel_mask());
|
||||
break;
|
||||
case FilterChannels:
|
||||
if (!capture_filter_button->get_active()) {
|
||||
return;
|
||||
if (capture_filter_button.get_active()) {
|
||||
track->set_capture_channel_mode (FilterChannels, track->get_capture_channel_mask());
|
||||
}
|
||||
track->set_capture_channel_mode (FilterChannels, track->get_capture_channel_mask());
|
||||
break;
|
||||
case ForceChannel:
|
||||
if (!capture_force_button->get_active()) {
|
||||
return;
|
||||
if (capture_force_button.get_active()) {
|
||||
track->set_capture_channel_mode (ForceChannel, track->get_capture_channel_mask());
|
||||
}
|
||||
track->set_capture_channel_mode (ForceChannel, track->get_capture_channel_mask());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -625,27 +832,25 @@ MidiChannelSelectorWindow::playback_mode_toggled (ChannelMode mode)
|
|||
is for the button/mode that has been turned off, and the second is for the
|
||||
button/mode that has been turned on.
|
||||
|
||||
so we have to check the button state to know what to do.
|
||||
so we take action only if the button is active (i.e it is the one
|
||||
just clicked on)
|
||||
*/
|
||||
|
||||
|
||||
switch (mode) {
|
||||
case AllChannels:
|
||||
if (!playback_all_button->get_active()) {
|
||||
return;
|
||||
if (playback_all_button.get_active()) {
|
||||
track->set_playback_channel_mode (AllChannels, track->get_playback_channel_mask());
|
||||
}
|
||||
track->set_playback_channel_mode (AllChannels, track->get_playback_channel_mask());
|
||||
break;
|
||||
case FilterChannels:
|
||||
if (!playback_filter_button->get_active()) {
|
||||
return;
|
||||
if (playback_filter_button.get_active()) {
|
||||
track->set_playback_channel_mode (FilterChannels, track->get_playback_channel_mask());
|
||||
}
|
||||
track->set_playback_channel_mode (FilterChannels, track->get_playback_channel_mask());
|
||||
break;
|
||||
case ForceChannel:
|
||||
if (!playback_force_button->get_active()) {
|
||||
return;
|
||||
if (playback_force_button.get_active()) {
|
||||
track->set_playback_channel_mode (ForceChannel, track->get_playback_channel_mask());
|
||||
}
|
||||
track->set_playback_channel_mode (ForceChannel, track->get_playback_channel_mask());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,79 +40,79 @@ namespace ARDOUR {
|
|||
|
||||
class MidiChannelSelector : public Gtk::Table
|
||||
{
|
||||
public:
|
||||
MidiChannelSelector(int n_rows = 4, int n_columns = 4, int start_row = 0, int start_column = 0);
|
||||
virtual ~MidiChannelSelector() = 0;
|
||||
public:
|
||||
MidiChannelSelector(int n_rows = 4, int n_columns = 4, int start_row = 0, int start_column = 0);
|
||||
virtual ~MidiChannelSelector() = 0;
|
||||
|
||||
sigc::signal<void> clicked;
|
||||
sigc::signal<void> clicked;
|
||||
|
||||
void set_channel_colors(const uint32_t new_channel_colors[16]);
|
||||
void set_default_channel_color();
|
||||
void set_channel_colors(const uint32_t new_channel_colors[16]);
|
||||
void set_default_channel_color();
|
||||
|
||||
protected:
|
||||
virtual void button_toggled(Gtk::ToggleButton* button, uint8_t button_nr) = 0;
|
||||
Gtk::Label _button_labels[4][4];
|
||||
Gtkmm2ext::StatefulToggleButton _buttons[4][4];
|
||||
int _recursion_counter;
|
||||
protected:
|
||||
virtual void button_toggled(Gtk::ToggleButton* button, uint8_t button_nr) = 0;
|
||||
Gtk::Label _button_labels[4][4];
|
||||
Gtkmm2ext::StatefulToggleButton _buttons[4][4];
|
||||
int _recursion_counter;
|
||||
|
||||
bool was_clicked (GdkEventButton*);
|
||||
bool was_clicked (GdkEventButton*);
|
||||
};
|
||||
|
||||
class SingleMidiChannelSelector : public MidiChannelSelector
|
||||
{
|
||||
public:
|
||||
SingleMidiChannelSelector(uint8_t active_channel = 0);
|
||||
public:
|
||||
SingleMidiChannelSelector(uint8_t active_channel = 0);
|
||||
|
||||
uint8_t get_active_channel() const { return _active_channel; }
|
||||
uint8_t get_active_channel() const { return _active_channel; }
|
||||
|
||||
sigc::signal<void, uint8_t> channel_selected;
|
||||
sigc::signal<void, uint8_t> channel_selected;
|
||||
|
||||
protected:
|
||||
virtual void button_toggled(Gtk::ToggleButton* button, uint8_t button_nr);
|
||||
protected:
|
||||
virtual void button_toggled(Gtk::ToggleButton* button, uint8_t button_nr);
|
||||
|
||||
Gtk::ToggleButton* _last_active_button;
|
||||
uint8_t _active_channel;
|
||||
Gtk::ToggleButton* _last_active_button;
|
||||
uint8_t _active_channel;
|
||||
};
|
||||
|
||||
class MidiMultipleChannelSelector : public MidiChannelSelector
|
||||
{
|
||||
public:
|
||||
MidiMultipleChannelSelector(ARDOUR::ChannelMode mode = ARDOUR::FilterChannels,
|
||||
uint16_t initial_selection = 0xFFFF);
|
||||
public:
|
||||
MidiMultipleChannelSelector(ARDOUR::ChannelMode mode = ARDOUR::FilterChannels,
|
||||
uint16_t initial_selection = 0xFFFF);
|
||||
|
||||
virtual ~MidiMultipleChannelSelector();
|
||||
virtual ~MidiMultipleChannelSelector();
|
||||
|
||||
/** The channel mode or selected channel(s) has changed.
|
||||
* First parameter is the new channel mode, second parameter is a bitmask
|
||||
* of the currently selected channels.
|
||||
*/
|
||||
sigc::signal<void, ARDOUR::ChannelMode, uint16_t> mode_changed;
|
||||
/** The channel mode or selected channel(s) has changed.
|
||||
* First parameter is the new channel mode, second parameter is a bitmask
|
||||
* of the currently selected channels.
|
||||
*/
|
||||
sigc::signal<void, ARDOUR::ChannelMode, uint16_t> mode_changed;
|
||||
|
||||
void set_channel_mode(ARDOUR::ChannelMode mode, uint16_t mask);
|
||||
ARDOUR::ChannelMode get_channel_mode () const { return _channel_mode; }
|
||||
void set_channel_mode(ARDOUR::ChannelMode mode, uint16_t mask);
|
||||
ARDOUR::ChannelMode get_channel_mode () const { return _channel_mode; }
|
||||
|
||||
/**
|
||||
* @return each bit in the returned word represents a midi channel, eg.
|
||||
* bit 0 represents channel 0 and bit 15 represents channel 15
|
||||
*
|
||||
*/
|
||||
uint16_t get_selected_channels() const;
|
||||
void set_selected_channels(uint16_t selected_channels);
|
||||
/**
|
||||
* @return each bit in the returned word represents a midi channel, eg.
|
||||
* bit 0 represents channel 0 and bit 15 represents channel 15
|
||||
*
|
||||
*/
|
||||
uint16_t get_selected_channels() const;
|
||||
void set_selected_channels(uint16_t selected_channels);
|
||||
|
||||
protected:
|
||||
ARDOUR::ChannelMode _channel_mode;
|
||||
ARDOUR::NoteMode _note_mode;
|
||||
protected:
|
||||
ARDOUR::ChannelMode _channel_mode;
|
||||
ARDOUR::NoteMode _note_mode;
|
||||
|
||||
virtual void button_toggled(Gtk::ToggleButton* button, uint8_t button_nr);
|
||||
void force_channels_button_toggled();
|
||||
virtual void button_toggled(Gtk::ToggleButton* button, uint8_t button_nr);
|
||||
void force_channels_button_toggled();
|
||||
|
||||
void select_all(bool on);
|
||||
void invert_selection(void);
|
||||
void select_all(bool on);
|
||||
void invert_selection(void);
|
||||
|
||||
Gtk::Button _select_all;
|
||||
Gtk::Button _select_none;
|
||||
Gtk::Button _invert_selection;
|
||||
Gtk::ToggleButton _force_channel;
|
||||
Gtk::Button _select_all;
|
||||
Gtk::Button _select_none;
|
||||
Gtk::Button _invert_selection;
|
||||
Gtk::ToggleButton _force_channel;
|
||||
};
|
||||
|
||||
class MidiChannelSelectorWindow : public ArdourWindow, public PBD::ScopedConnectionList
|
||||
|
@ -129,12 +129,22 @@ class MidiChannelSelectorWindow : public ArdourWindow, public PBD::ScopedConnect
|
|||
std::vector<Gtk::ToggleButton*> playback_buttons;
|
||||
std::vector<Gtk::ToggleButton*> capture_buttons;
|
||||
|
||||
Gtk::ToggleButton* playback_all_button;
|
||||
Gtk::ToggleButton* playback_filter_button;
|
||||
Gtk::ToggleButton* playback_force_button;
|
||||
Gtk::ToggleButton* capture_all_button;
|
||||
Gtk::ToggleButton* capture_filter_button;
|
||||
Gtk::ToggleButton* capture_force_button;
|
||||
std::vector<Gtk::Widget*> playback_mask_controls;
|
||||
std::vector<Gtk::Widget*> capture_mask_controls;
|
||||
|
||||
Gtk::HBox capture_mask_box;
|
||||
Gtk::HBox playback_mask_box;
|
||||
Gtk::RadioButtonGroup playback_button_group;
|
||||
Gtk::RadioButton playback_all_button;
|
||||
Gtk::RadioButton playback_filter_button;
|
||||
Gtk::RadioButton playback_force_button;
|
||||
Gtk::RadioButtonGroup capture_button_group;
|
||||
Gtk::RadioButton capture_all_button;
|
||||
Gtk::RadioButton capture_filter_button;
|
||||
Gtk::RadioButton capture_force_button;
|
||||
|
||||
ARDOUR::ChannelMode last_drawn_capture_mode;
|
||||
ARDOUR::ChannelMode last_drawn_playback_mode;
|
||||
|
||||
void build();
|
||||
void set_capture_selected_channels (uint16_t);
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
#include <cstdlib>
|
||||
#include <cmath>
|
||||
|
||||
#include <strings.h> // for ffs(3)
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
@ -95,7 +97,7 @@ using namespace Gtkmm2ext;
|
|||
using namespace Editing;
|
||||
|
||||
// Minimum height at which a control is displayed
|
||||
static const uint32_t MIDI_CONTROLS_BOX_MIN_HEIGHT = 130;
|
||||
static const uint32_t MIDI_CONTROLS_BOX_MIN_HEIGHT = 140;
|
||||
static const uint32_t KEYBOARD_MIN_HEIGHT = 130;
|
||||
|
||||
MidiTimeAxisView::MidiTimeAxisView (PublicEditor& ed, Session* sess, Canvas& canvas)
|
||||
|
@ -212,6 +214,22 @@ MidiTimeAxisView::set_route (boost::shared_ptr<Route> rt)
|
|||
_view->RegionViewAdded.connect (
|
||||
sigc::mem_fun(*this, &MidiTimeAxisView::region_view_added));
|
||||
|
||||
midi_track()->PlaybackChannelModeChanged.connect (*this, invalidator (*this),
|
||||
boost::bind (&MidiTimeAxisView::playback_channel_mode_changed, this),
|
||||
gui_context());
|
||||
midi_track()->PlaybackChannelMaskChanged.connect (*this, invalidator (*this),
|
||||
boost::bind (&MidiTimeAxisView::playback_channel_mode_changed, this),
|
||||
gui_context());
|
||||
midi_track()->CaptureChannelModeChanged.connect (*this, invalidator (*this),
|
||||
boost::bind (&MidiTimeAxisView::capture_channel_mode_changed, this),
|
||||
gui_context());
|
||||
midi_track()->CaptureChannelMaskChanged.connect (*this, invalidator (*this),
|
||||
boost::bind (&MidiTimeAxisView::capture_channel_mode_changed, this),
|
||||
gui_context());
|
||||
|
||||
playback_channel_mode_changed ();
|
||||
capture_channel_mode_changed ();
|
||||
|
||||
if (!_editor.have_idled()) {
|
||||
/* first idle will do what we need */
|
||||
} else {
|
||||
|
@ -247,19 +265,37 @@ MidiTimeAxisView::set_route (boost::shared_ptr<Route> rt)
|
|||
_midi_controls_box.set_homogeneous(false);
|
||||
_midi_controls_box.set_border_width (10);
|
||||
|
||||
_channel_status_box.set_homogeneous (false);
|
||||
_channel_status_box.set_spacing (6);
|
||||
|
||||
_channel_selector_button.set_label (_("Chns"));
|
||||
|
||||
/* fixed sized labels to prevent silly nonsense */
|
||||
|
||||
_playback_channel_status.set_size_request (65, -1);
|
||||
_capture_channel_status.set_size_request (60, -1);
|
||||
|
||||
_channel_status_box.pack_start (_playback_channel_status, false, false);
|
||||
_channel_status_box.pack_start (_capture_channel_status, false, false);
|
||||
_channel_status_box.pack_start (_channel_selector_button, false, false);
|
||||
_channel_status_box.show_all ();
|
||||
|
||||
_channel_selector_button.signal_clicked().connect (sigc::mem_fun (*this, &MidiTimeAxisView::toggle_channel_selector));
|
||||
|
||||
_midi_controls_box.pack_start (_channel_status_box, false, false, 10);
|
||||
|
||||
if (!patch_manager.all_models().empty()) {
|
||||
_midi_controls_box.resize(2, 2);
|
||||
|
||||
_midnam_model_selector.set_size_request(22, 30);
|
||||
_midnam_model_selector.set_border_width(2);
|
||||
_midnam_model_selector.show ();
|
||||
_midi_controls_box.attach(_midnam_model_selector, 0, 1, 0, 1);
|
||||
_midi_controls_box.pack_start (_midnam_model_selector);
|
||||
|
||||
_midnam_custom_device_mode_selector.set_size_request(10, 30);
|
||||
_midnam_custom_device_mode_selector.set_border_width(2);
|
||||
_midnam_custom_device_mode_selector.show ();
|
||||
|
||||
_midi_controls_box.attach(_midnam_custom_device_mode_selector, 0, 1, 1, 2);
|
||||
_midi_controls_box.pack_start (_midnam_custom_device_mode_selector);
|
||||
}
|
||||
|
||||
model_changed();
|
||||
|
@ -478,6 +514,7 @@ MidiTimeAxisView::toggle_channel_selector ()
|
|||
_channel_selector->set_default_channel_color ();
|
||||
}
|
||||
|
||||
_channel_selector->set_position (WIN_POS_MOUSE);
|
||||
_channel_selector->show_all ();
|
||||
} else {
|
||||
_channel_selector->cycle_visibility ();
|
||||
|
@ -1440,3 +1477,35 @@ MidiTimeAxisView::contents_height_changed ()
|
|||
{
|
||||
_range_scroomer->set_size_request (-1, _view->child_height ());
|
||||
}
|
||||
|
||||
void
|
||||
MidiTimeAxisView::playback_channel_mode_changed ()
|
||||
{
|
||||
switch (midi_track()->get_playback_channel_mode()) {
|
||||
case AllChannels:
|
||||
_playback_channel_status.set_markup (string_compose ("<b>%1</b>: <i>%2</i>", _("Play"), ("all")));
|
||||
break;
|
||||
case FilterChannels:
|
||||
_playback_channel_status.set_markup (string_compose ("<b>%1</b>: <i>%2</i>", _("Play"), ("some")));
|
||||
break;
|
||||
case ForceChannel:
|
||||
_playback_channel_status.set_markup (string_compose ("<b>%1</b>: <i>%2>%3</i>", _("Play"), ("all"), ffs (midi_track()->get_playback_channel_mask())));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MidiTimeAxisView::capture_channel_mode_changed ()
|
||||
{
|
||||
switch (midi_track()->get_capture_channel_mode()) {
|
||||
case AllChannels:
|
||||
_capture_channel_status.set_markup (string_compose ("<b>%1</b>: <i>%2</i>", _("Rec"), ("all")));
|
||||
break;
|
||||
case FilterChannels:
|
||||
_capture_channel_status.set_markup (string_compose ("<b>%1</b>: <i>%2</i>", _("Rec"), ("some")));
|
||||
break;
|
||||
case ForceChannel:
|
||||
_capture_channel_status.set_markup (string_compose ("<b>%1</b>: <i>%2>%3</i>", _("Rec"), ("all"), ffs (midi_track()->get_capture_channel_mask())));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -134,7 +134,11 @@ class MidiTimeAxisView : public RouteTimeAxisView
|
|||
Gtk::RadioMenuItem* _meter_color_mode_item;
|
||||
Gtk::RadioMenuItem* _channel_color_mode_item;
|
||||
Gtk::RadioMenuItem* _track_color_mode_item;
|
||||
Gtk::Table _midi_controls_box;
|
||||
Gtk::Label _playback_channel_status;
|
||||
Gtk::Label _capture_channel_status;
|
||||
Gtk::HBox _channel_status_box;
|
||||
Gtk::Button _channel_selector_button;
|
||||
Gtk::VBox _midi_controls_box;
|
||||
MidiChannelSelectorWindow* _channel_selector;
|
||||
Gtk::ComboBoxText _midnam_model_selector;
|
||||
Gtk::ComboBoxText _midnam_custom_device_mode_selector;
|
||||
|
@ -172,6 +176,9 @@ class MidiTimeAxisView : public RouteTimeAxisView
|
|||
ParameterMenuMap _controller_menu_map;
|
||||
|
||||
StepEditor* _step_editor;
|
||||
|
||||
void capture_channel_mode_changed();
|
||||
void playback_channel_mode_changed();
|
||||
};
|
||||
|
||||
#endif /* __ardour_midi_time_axis_h__ */
|
||||
|
|
Loading…
Reference in New Issue
Block a user