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
|
Copyright (C) 2008-2013 Paul Davis
|
||||||
Author: Hans Baier
|
Original Author: Hans Baier
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
#include "gtkmm2ext/gtk_ui.h"
|
#include "gtkmm2ext/gtk_ui.h"
|
||||||
#include "gtkmm2ext/gui_thread.h"
|
#include "gtkmm2ext/gui_thread.h"
|
||||||
|
#include "gtkmm2ext/utils.h"
|
||||||
|
|
||||||
#include "ardour/midi_track.h"
|
#include "ardour/midi_track.h"
|
||||||
|
|
||||||
@ -326,16 +327,25 @@ MidiMultipleChannelSelector::invert_selection(void)
|
|||||||
/*-----------------------------------------*/
|
/*-----------------------------------------*/
|
||||||
|
|
||||||
MidiChannelSelectorWindow::MidiChannelSelectorWindow (boost::shared_ptr<MidiTrack> mt)
|
MidiChannelSelectorWindow::MidiChannelSelectorWindow (boost::shared_ptr<MidiTrack> mt)
|
||||||
: ArdourWindow (string_compose (_("MIDI Channel Control for %1"), mt->name()))
|
: ArdourWindow (_("MIDI Channel Control"))
|
||||||
, track (mt)
|
, 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 ();
|
build ();
|
||||||
|
|
||||||
playback_mask_changed ();
|
|
||||||
playback_mode_changed ();
|
playback_mode_changed ();
|
||||||
capture_mask_changed ();
|
|
||||||
capture_mode_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->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->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());
|
track->CaptureChannelMaskChanged.connect (*this, MISSING_INVALIDATOR, boost::bind (&MidiChannelSelectorWindow::capture_mask_changed, this), gui_context());
|
||||||
@ -350,122 +360,93 @@ void
|
|||||||
MidiChannelSelectorWindow::build ()
|
MidiChannelSelectorWindow::build ()
|
||||||
{
|
{
|
||||||
VBox* vpacker;
|
VBox* vpacker;
|
||||||
HBox* capture_mask;
|
HBox* capture_controls;
|
||||||
HBox* capture_mask_controls;
|
HBox* playback_controls;
|
||||||
HBox* playback_mask;
|
|
||||||
HBox* playback_mask_controls;
|
|
||||||
Button* b;
|
Button* b;
|
||||||
ToggleButton* tb;
|
|
||||||
Label* l;
|
Label* l;
|
||||||
|
|
||||||
vpacker = manage (new VBox);
|
vpacker = manage (new VBox);
|
||||||
vpacker->set_spacing (6);
|
vpacker->set_spacing (6);
|
||||||
vpacker->set_border_width (12);
|
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);
|
l->set_use_markup (true);
|
||||||
vpacker->pack_start (*l);
|
vpacker->pack_start (*l);
|
||||||
|
|
||||||
{
|
|
||||||
RadioButtonGroup group;
|
|
||||||
|
|
||||||
capture_all_button = manage (new RadioButton (group, "Record all channels"));
|
vpacker->pack_start (capture_all_button);
|
||||||
vpacker->pack_start (*capture_all_button);
|
capture_all_button.signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiChannelSelectorWindow::capture_mode_toggled), AllChannels));
|
||||||
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_mask_box);
|
||||||
vpacker->pack_start (*capture_filter_button);
|
|
||||||
capture_filter_button->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiChannelSelectorWindow::capture_mode_toggled), FilterChannels));
|
capture_controls = manage (new HBox);
|
||||||
|
capture_controls->set_spacing (6);
|
||||||
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);
|
|
||||||
|
|
||||||
b = manage (new Button (_("All")));
|
b = manage (new Button (_("All")));
|
||||||
Gtkmm2ext::UI::instance()->set_tip (*b, _("Click to enable recording all channels"));
|
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->signal_clicked().connect (sigc::mem_fun (*this, &MidiChannelSelectorWindow::fill_capture_mask));
|
||||||
b = manage (new Button (_("None")));
|
b = manage (new Button (_("None")));
|
||||||
Gtkmm2ext::UI::instance()->set_tip (*b, _("Click to disable recording all channels"));
|
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->signal_clicked().connect (sigc::mem_fun (*this, &MidiChannelSelectorWindow::zero_capture_mask));
|
||||||
b = manage (new Button (_("Invert")));
|
b = manage (new Button (_("Invert")));
|
||||||
Gtkmm2ext::UI::instance()->set_tip (*b, _("Click to invert currently selected recording channels"));
|
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));
|
b->signal_clicked().connect (sigc::mem_fun (*this, &MidiChannelSelectorWindow::invert_capture_mask));
|
||||||
|
|
||||||
vpacker->pack_start (*capture_mask_controls);
|
vpacker->pack_start (*capture_controls);
|
||||||
|
|
||||||
playback_mask = manage (new HBox);
|
|
||||||
|
|
||||||
l = manage (new Label (string_compose ("<span size=\"large\" weight=\"bold\">%1</span>", _("Playback"))));
|
l = manage (new Label (string_compose ("<span size=\"large\" weight=\"bold\">%1</span>", _("Playback"))));
|
||||||
l->set_use_markup (true);
|
l->set_use_markup (true);
|
||||||
vpacker->pack_start (*l);
|
vpacker->pack_start (*l);
|
||||||
|
|
||||||
{
|
vpacker->pack_start (playback_all_button);
|
||||||
RadioButtonGroup group;
|
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_mask_box);
|
||||||
vpacker->pack_start (*playback_all_button);
|
|
||||||
playback_all_button->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiChannelSelectorWindow::playback_mode_toggled), AllChannels));
|
|
||||||
|
|
||||||
playback_filter_button = manage (new RadioButton (group, "Play only selected channels"));
|
playback_controls = manage (new HBox);
|
||||||
vpacker->pack_start (*playback_filter_button);
|
playback_controls->set_spacing (6);
|
||||||
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);
|
|
||||||
|
|
||||||
b = manage (new Button (_("All")));
|
b = manage (new Button (_("All")));
|
||||||
Gtkmm2ext::UI::instance()->set_tip (*b, _("Click to enable playback of all channels"));
|
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->signal_clicked().connect (sigc::mem_fun (*this, &MidiChannelSelectorWindow::fill_playback_mask));
|
||||||
b = manage (new Button (_("None")));
|
b = manage (new Button (_("None")));
|
||||||
Gtkmm2ext::UI::instance()->set_tip (*b, _("Click to disable playback of all channels"));
|
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->signal_clicked().connect (sigc::mem_fun (*this, &MidiChannelSelectorWindow::zero_playback_mask));
|
||||||
b = manage (new Button (_("Invert")));
|
b = manage (new Button (_("Invert")));
|
||||||
Gtkmm2ext::UI::instance()->set_tip (*b, _("Click to invert current selected playback channels"));
|
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));
|
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);
|
add (*vpacker);
|
||||||
}
|
}
|
||||||
@ -473,52 +454,94 @@ MidiChannelSelectorWindow::build ()
|
|||||||
void
|
void
|
||||||
MidiChannelSelectorWindow::fill_playback_mask ()
|
MidiChannelSelectorWindow::fill_playback_mask ()
|
||||||
{
|
{
|
||||||
track->set_playback_channel_mask (0xffff);
|
if (track->get_playback_channel_mode() == FilterChannels) {
|
||||||
|
track->set_playback_channel_mask (0xffff);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MidiChannelSelectorWindow::zero_playback_mask ()
|
MidiChannelSelectorWindow::zero_playback_mask ()
|
||||||
{
|
{
|
||||||
track->set_playback_channel_mask (0);
|
if (track->get_playback_channel_mode() == FilterChannels) {
|
||||||
|
track->set_playback_channel_mask (0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MidiChannelSelectorWindow::invert_playback_mask ()
|
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
|
void
|
||||||
MidiChannelSelectorWindow::fill_capture_mask ()
|
MidiChannelSelectorWindow::fill_capture_mask ()
|
||||||
{
|
{
|
||||||
track->set_capture_channel_mask (0xffff);
|
if (track->get_capture_channel_mode() == FilterChannels) {
|
||||||
|
track->set_capture_channel_mask (0xffff);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MidiChannelSelectorWindow::zero_capture_mask ()
|
MidiChannelSelectorWindow::zero_capture_mask ()
|
||||||
{
|
{
|
||||||
track->set_capture_channel_mask (0);
|
if (track->get_capture_channel_mode() == FilterChannels) {
|
||||||
|
track->set_capture_channel_mask (0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MidiChannelSelectorWindow::invert_capture_mask ()
|
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
|
void
|
||||||
MidiChannelSelectorWindow::set_playback_selected_channels (uint16_t mask)
|
MidiChannelSelectorWindow::set_playback_selected_channels (uint16_t mask)
|
||||||
{
|
{
|
||||||
for (uint16_t i = 0; i < 16; i++) {
|
switch (track->get_playback_channel_mode()) {
|
||||||
playback_buttons[i]->set_active ((1<<i) & mask);
|
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
|
void
|
||||||
MidiChannelSelectorWindow::set_capture_selected_channels (uint16_t mask)
|
MidiChannelSelectorWindow::set_capture_selected_channels (uint16_t mask)
|
||||||
{
|
{
|
||||||
for (uint16_t i = 0; i < 16; i++) {
|
switch (track->get_capture_channel_mode()) {
|
||||||
capture_buttons[i]->set_active ((1<<i) & mask);
|
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
|
void
|
||||||
MidiChannelSelectorWindow::playback_mode_changed ()
|
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:
|
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;
|
break;
|
||||||
|
|
||||||
case FilterChannels:
|
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;
|
break;
|
||||||
|
|
||||||
case ForceChannel:
|
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;
|
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
|
void
|
||||||
MidiChannelSelectorWindow::capture_mode_changed ()
|
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:
|
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;
|
break;
|
||||||
|
|
||||||
case FilterChannels:
|
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;
|
break;
|
||||||
|
|
||||||
case ForceChannel:
|
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;
|
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
|
void
|
||||||
MidiChannelSelectorWindow::playback_channel_clicked (uint16_t n)
|
MidiChannelSelectorWindow::playback_channel_clicked (uint16_t n)
|
||||||
{
|
{
|
||||||
if (playback_buttons[n]->get_active()) {
|
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 {
|
} 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)
|
MidiChannelSelectorWindow::capture_channel_clicked (uint16_t n)
|
||||||
{
|
{
|
||||||
if (capture_buttons[n]->get_active()) {
|
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 {
|
} 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
|
is for the button/mode that has been turned off, and the second is for the
|
||||||
button/mode that has been turned on.
|
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) {
|
switch (mode) {
|
||||||
case AllChannels:
|
case AllChannels:
|
||||||
if (!capture_all_button->get_active()) {
|
if (capture_all_button.get_active()) {
|
||||||
return;
|
track->set_capture_channel_mode (AllChannels, track->get_capture_channel_mask());
|
||||||
}
|
}
|
||||||
track->set_capture_channel_mode (AllChannels, track->get_capture_channel_mask());
|
|
||||||
break;
|
break;
|
||||||
case FilterChannels:
|
case FilterChannels:
|
||||||
if (!capture_filter_button->get_active()) {
|
if (capture_filter_button.get_active()) {
|
||||||
return;
|
track->set_capture_channel_mode (FilterChannels, track->get_capture_channel_mask());
|
||||||
}
|
}
|
||||||
track->set_capture_channel_mode (FilterChannels, track->get_capture_channel_mask());
|
|
||||||
break;
|
break;
|
||||||
case ForceChannel:
|
case ForceChannel:
|
||||||
if (!capture_force_button->get_active()) {
|
if (capture_force_button.get_active()) {
|
||||||
return;
|
track->set_capture_channel_mode (ForceChannel, track->get_capture_channel_mask());
|
||||||
}
|
}
|
||||||
track->set_capture_channel_mode (ForceChannel, track->get_capture_channel_mask());
|
|
||||||
break;
|
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
|
is for the button/mode that has been turned off, and the second is for the
|
||||||
button/mode that has been turned on.
|
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) {
|
switch (mode) {
|
||||||
case AllChannels:
|
case AllChannels:
|
||||||
if (!playback_all_button->get_active()) {
|
if (playback_all_button.get_active()) {
|
||||||
return;
|
track->set_playback_channel_mode (AllChannels, track->get_playback_channel_mask());
|
||||||
}
|
}
|
||||||
track->set_playback_channel_mode (AllChannels, track->get_playback_channel_mask());
|
|
||||||
break;
|
break;
|
||||||
case FilterChannels:
|
case FilterChannels:
|
||||||
if (!playback_filter_button->get_active()) {
|
if (playback_filter_button.get_active()) {
|
||||||
return;
|
track->set_playback_channel_mode (FilterChannels, track->get_playback_channel_mask());
|
||||||
}
|
}
|
||||||
track->set_playback_channel_mode (FilterChannels, track->get_playback_channel_mask());
|
|
||||||
break;
|
break;
|
||||||
case ForceChannel:
|
case ForceChannel:
|
||||||
if (!playback_force_button->get_active()) {
|
if (playback_force_button.get_active()) {
|
||||||
return;
|
track->set_playback_channel_mode (ForceChannel, track->get_playback_channel_mask());
|
||||||
}
|
}
|
||||||
track->set_playback_channel_mode (ForceChannel, track->get_playback_channel_mask());
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,79 +40,79 @@ namespace ARDOUR {
|
|||||||
|
|
||||||
class MidiChannelSelector : public Gtk::Table
|
class MidiChannelSelector : public Gtk::Table
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MidiChannelSelector(int n_rows = 4, int n_columns = 4, int start_row = 0, int start_column = 0);
|
MidiChannelSelector(int n_rows = 4, int n_columns = 4, int start_row = 0, int start_column = 0);
|
||||||
virtual ~MidiChannelSelector() = 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_channel_colors(const uint32_t new_channel_colors[16]);
|
||||||
void set_default_channel_color();
|
void set_default_channel_color();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void button_toggled(Gtk::ToggleButton* button, uint8_t button_nr) = 0;
|
virtual void button_toggled(Gtk::ToggleButton* button, uint8_t button_nr) = 0;
|
||||||
Gtk::Label _button_labels[4][4];
|
Gtk::Label _button_labels[4][4];
|
||||||
Gtkmm2ext::StatefulToggleButton _buttons[4][4];
|
Gtkmm2ext::StatefulToggleButton _buttons[4][4];
|
||||||
int _recursion_counter;
|
int _recursion_counter;
|
||||||
|
|
||||||
bool was_clicked (GdkEventButton*);
|
bool was_clicked (GdkEventButton*);
|
||||||
};
|
};
|
||||||
|
|
||||||
class SingleMidiChannelSelector : public MidiChannelSelector
|
class SingleMidiChannelSelector : public MidiChannelSelector
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SingleMidiChannelSelector(uint8_t active_channel = 0);
|
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:
|
protected:
|
||||||
virtual void button_toggled(Gtk::ToggleButton* button, uint8_t button_nr);
|
virtual void button_toggled(Gtk::ToggleButton* button, uint8_t button_nr);
|
||||||
|
|
||||||
Gtk::ToggleButton* _last_active_button;
|
Gtk::ToggleButton* _last_active_button;
|
||||||
uint8_t _active_channel;
|
uint8_t _active_channel;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MidiMultipleChannelSelector : public MidiChannelSelector
|
class MidiMultipleChannelSelector : public MidiChannelSelector
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MidiMultipleChannelSelector(ARDOUR::ChannelMode mode = ARDOUR::FilterChannels,
|
MidiMultipleChannelSelector(ARDOUR::ChannelMode mode = ARDOUR::FilterChannels,
|
||||||
uint16_t initial_selection = 0xFFFF);
|
uint16_t initial_selection = 0xFFFF);
|
||||||
|
|
||||||
virtual ~MidiMultipleChannelSelector();
|
virtual ~MidiMultipleChannelSelector();
|
||||||
|
|
||||||
/** The channel mode or selected channel(s) has changed.
|
/** The channel mode or selected channel(s) has changed.
|
||||||
* First parameter is the new channel mode, second parameter is a bitmask
|
* First parameter is the new channel mode, second parameter is a bitmask
|
||||||
* of the currently selected channels.
|
* of the currently selected channels.
|
||||||
*/
|
*/
|
||||||
sigc::signal<void, ARDOUR::ChannelMode, uint16_t> mode_changed;
|
sigc::signal<void, ARDOUR::ChannelMode, uint16_t> mode_changed;
|
||||||
|
|
||||||
void set_channel_mode(ARDOUR::ChannelMode mode, uint16_t mask);
|
void set_channel_mode(ARDOUR::ChannelMode mode, uint16_t mask);
|
||||||
ARDOUR::ChannelMode get_channel_mode () const { return _channel_mode; }
|
ARDOUR::ChannelMode get_channel_mode () const { return _channel_mode; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return each bit in the returned word represents a midi channel, eg.
|
* @return each bit in the returned word represents a midi channel, eg.
|
||||||
* bit 0 represents channel 0 and bit 15 represents channel 15
|
* bit 0 represents channel 0 and bit 15 represents channel 15
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
uint16_t get_selected_channels() const;
|
uint16_t get_selected_channels() const;
|
||||||
void set_selected_channels(uint16_t selected_channels);
|
void set_selected_channels(uint16_t selected_channels);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ARDOUR::ChannelMode _channel_mode;
|
ARDOUR::ChannelMode _channel_mode;
|
||||||
ARDOUR::NoteMode _note_mode;
|
ARDOUR::NoteMode _note_mode;
|
||||||
|
|
||||||
virtual void button_toggled(Gtk::ToggleButton* button, uint8_t button_nr);
|
virtual void button_toggled(Gtk::ToggleButton* button, uint8_t button_nr);
|
||||||
void force_channels_button_toggled();
|
void force_channels_button_toggled();
|
||||||
|
|
||||||
void select_all(bool on);
|
void select_all(bool on);
|
||||||
void invert_selection(void);
|
void invert_selection(void);
|
||||||
|
|
||||||
Gtk::Button _select_all;
|
Gtk::Button _select_all;
|
||||||
Gtk::Button _select_none;
|
Gtk::Button _select_none;
|
||||||
Gtk::Button _invert_selection;
|
Gtk::Button _invert_selection;
|
||||||
Gtk::ToggleButton _force_channel;
|
Gtk::ToggleButton _force_channel;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MidiChannelSelectorWindow : public ArdourWindow, public PBD::ScopedConnectionList
|
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*> playback_buttons;
|
||||||
std::vector<Gtk::ToggleButton*> capture_buttons;
|
std::vector<Gtk::ToggleButton*> capture_buttons;
|
||||||
|
|
||||||
Gtk::ToggleButton* playback_all_button;
|
std::vector<Gtk::Widget*> playback_mask_controls;
|
||||||
Gtk::ToggleButton* playback_filter_button;
|
std::vector<Gtk::Widget*> capture_mask_controls;
|
||||||
Gtk::ToggleButton* playback_force_button;
|
|
||||||
Gtk::ToggleButton* capture_all_button;
|
Gtk::HBox capture_mask_box;
|
||||||
Gtk::ToggleButton* capture_filter_button;
|
Gtk::HBox playback_mask_box;
|
||||||
Gtk::ToggleButton* capture_force_button;
|
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 build();
|
||||||
void set_capture_selected_channels (uint16_t);
|
void set_capture_selected_channels (uint16_t);
|
||||||
|
@ -19,6 +19,8 @@
|
|||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
|
#include <strings.h> // for ffs(3)
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -95,7 +97,7 @@ using namespace Gtkmm2ext;
|
|||||||
using namespace Editing;
|
using namespace Editing;
|
||||||
|
|
||||||
// Minimum height at which a control is displayed
|
// 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;
|
static const uint32_t KEYBOARD_MIN_HEIGHT = 130;
|
||||||
|
|
||||||
MidiTimeAxisView::MidiTimeAxisView (PublicEditor& ed, Session* sess, Canvas& canvas)
|
MidiTimeAxisView::MidiTimeAxisView (PublicEditor& ed, Session* sess, Canvas& canvas)
|
||||||
@ -212,6 +214,22 @@ MidiTimeAxisView::set_route (boost::shared_ptr<Route> rt)
|
|||||||
_view->RegionViewAdded.connect (
|
_view->RegionViewAdded.connect (
|
||||||
sigc::mem_fun(*this, &MidiTimeAxisView::region_view_added));
|
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()) {
|
if (!_editor.have_idled()) {
|
||||||
/* first idle will do what we need */
|
/* first idle will do what we need */
|
||||||
} else {
|
} else {
|
||||||
@ -247,19 +265,37 @@ MidiTimeAxisView::set_route (boost::shared_ptr<Route> rt)
|
|||||||
_midi_controls_box.set_homogeneous(false);
|
_midi_controls_box.set_homogeneous(false);
|
||||||
_midi_controls_box.set_border_width (10);
|
_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()) {
|
if (!patch_manager.all_models().empty()) {
|
||||||
_midi_controls_box.resize(2, 2);
|
|
||||||
|
|
||||||
_midnam_model_selector.set_size_request(22, 30);
|
_midnam_model_selector.set_size_request(22, 30);
|
||||||
_midnam_model_selector.set_border_width(2);
|
_midnam_model_selector.set_border_width(2);
|
||||||
_midnam_model_selector.show ();
|
_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_size_request(10, 30);
|
||||||
_midnam_custom_device_mode_selector.set_border_width(2);
|
_midnam_custom_device_mode_selector.set_border_width(2);
|
||||||
_midnam_custom_device_mode_selector.show ();
|
_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();
|
model_changed();
|
||||||
@ -478,6 +514,7 @@ MidiTimeAxisView::toggle_channel_selector ()
|
|||||||
_channel_selector->set_default_channel_color ();
|
_channel_selector->set_default_channel_color ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_channel_selector->set_position (WIN_POS_MOUSE);
|
||||||
_channel_selector->show_all ();
|
_channel_selector->show_all ();
|
||||||
} else {
|
} else {
|
||||||
_channel_selector->cycle_visibility ();
|
_channel_selector->cycle_visibility ();
|
||||||
@ -1440,3 +1477,35 @@ MidiTimeAxisView::contents_height_changed ()
|
|||||||
{
|
{
|
||||||
_range_scroomer->set_size_request (-1, _view->child_height ());
|
_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* _meter_color_mode_item;
|
||||||
Gtk::RadioMenuItem* _channel_color_mode_item;
|
Gtk::RadioMenuItem* _channel_color_mode_item;
|
||||||
Gtk::RadioMenuItem* _track_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;
|
MidiChannelSelectorWindow* _channel_selector;
|
||||||
Gtk::ComboBoxText _midnam_model_selector;
|
Gtk::ComboBoxText _midnam_model_selector;
|
||||||
Gtk::ComboBoxText _midnam_custom_device_mode_selector;
|
Gtk::ComboBoxText _midnam_custom_device_mode_selector;
|
||||||
@ -172,6 +176,9 @@ class MidiTimeAxisView : public RouteTimeAxisView
|
|||||||
ParameterMenuMap _controller_menu_map;
|
ParameterMenuMap _controller_menu_map;
|
||||||
|
|
||||||
StepEditor* _step_editor;
|
StepEditor* _step_editor;
|
||||||
|
|
||||||
|
void capture_channel_mode_changed();
|
||||||
|
void playback_channel_mode_changed();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* __ardour_midi_time_axis_h__ */
|
#endif /* __ardour_midi_time_axis_h__ */
|
||||||
|
Loading…
Reference in New Issue
Block a user