X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Fmidi_channel_selector.cc;h=1da8fd9c0059dfcc9e5179a067d0dde9c8a02014;hb=cf52d6e4b40111eb04b244ec054055a4ec15dbe0;hp=4415a65f6539ee6fabbf29940d67295cc7c0bf68;hpb=c3636a8c61401c2e487313566348e0f6d1fab990;p=ardour.git diff --git a/gtk2_ardour/midi_channel_selector.cc b/gtk2_ardour/midi_channel_selector.cc index 4415a65f65..1da8fd9c00 100644 --- a/gtk2_ardour/midi_channel_selector.cc +++ b/gtk2_ardour/midi_channel_selector.cc @@ -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 @@ -17,28 +17,42 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include #include +#include +#include +#include +#include +#include +#include + +#include "pbd/compose.h" +#include "pbd/ffs.h" + +#include "gtkmm2ext/gtk_ui.h" +#include "gtkmm2ext/gui_thread.h" +#include "gtkmm2ext/utils.h" + +#include "ardour/midi_track.h" + #include "midi_channel_selector.h" -#include "gtkmm/separator.h" -#include "i18n.h" #include "rgb_macros.h" +#include "pbd/i18n.h" + using namespace std; using namespace Gtk; -using namespace sigc; using namespace ARDOUR; -MidiChannelSelector::MidiChannelSelector(int no_rows, int no_columns, int start_row, int start_column) : Table(no_rows, no_columns, true) - , _recursion_counter(0) -{ - assert(no_rows >= 4); - assert(no_rows >= start_row + 4); - assert(no_columns >=4); - assert(no_columns >= start_column + 4); - +MidiChannelSelector::MidiChannelSelector(int n_rows, int n_columns, int start_row, int start_column) + : Table(std::max(4, std::max(n_rows, start_row + 4)), + std::max(4, std::max(n_columns, start_column + 4)), + true) + , _recursion_counter(0) +{ property_column_spacing() = 0; property_row_spacing() = 0; - + uint8_t channel_nr = 0; for (int row = 0; row < 4; ++row) { for (int column = 0; column < 4; ++column) { @@ -48,10 +62,14 @@ MidiChannelSelector::MidiChannelSelector(int no_rows, int no_columns, int start_ _button_labels[row][column].set_justify(JUSTIFY_RIGHT); _buttons[row][column].add(_button_labels[row][column]); _buttons[row][column].signal_toggled().connect( - bind( - mem_fun(this, &MidiChannelSelector::button_toggled), + sigc::bind( + sigc::mem_fun(this, &MidiChannelSelector::button_toggled), &_buttons[row][column], channel_nr - 1)); + _buttons[row][column].set_widget_name (X_("MidiChannelSelectorButton")); + + _buttons[row][column].signal_button_release_event().connect( + sigc::mem_fun(this, &MidiChannelSelector::was_clicked), false); int table_row = start_row + row; int table_column = start_column + column; @@ -64,6 +82,13 @@ MidiChannelSelector::~MidiChannelSelector() { } +bool +MidiChannelSelector::was_clicked (GdkEventButton*) +{ + clicked (); + return false; +} + void MidiChannelSelector::set_channel_colors(const uint32_t new_channel_colors[16]) { @@ -84,8 +109,10 @@ MidiChannelSelector::set_default_channel_color() { for (int row = 0; row < 4; ++row) { for (int column = 0; column < 4; ++column) { - _buttons[row][column].unset_bg(STATE_NORMAL); - _buttons[row][column].unset_bg(STATE_ACTIVE); + _buttons[row][column].unset_fg (STATE_NORMAL); + _buttons[row][column].unset_fg (STATE_ACTIVE); + _buttons[row][column].unset_bg (STATE_NORMAL); + _buttons[row][column].unset_bg (STATE_ACTIVE); } } } @@ -102,10 +129,10 @@ SingleMidiChannelSelector::SingleMidiChannelSelector(uint8_t active_channel) void SingleMidiChannelSelector::button_toggled(ToggleButton* button, uint8_t channel) -{ +{ ++_recursion_counter; if (_recursion_counter == 1) { - // if the current button is active it must + // if the current button is active it must // be different from the first one if (button->get_active()) { if (_last_active_button) { @@ -129,19 +156,19 @@ MidiMultipleChannelSelector::MidiMultipleChannelSelector(ChannelMode mode, uint1 { _select_all.add(*manage(new Label(_("All")))); _select_all.signal_clicked().connect( - bind(mem_fun(this, &MidiMultipleChannelSelector::select_all), true)); - + sigc::bind(sigc::mem_fun(this, &MidiMultipleChannelSelector::select_all), true)); + _select_none.add(*manage(new Label(_("None")))); _select_none.signal_clicked().connect( - bind(mem_fun(this, &MidiMultipleChannelSelector::select_all), false)); - + sigc::bind(sigc::mem_fun(this, &MidiMultipleChannelSelector::select_all), false)); + _invert_selection.add(*manage(new Label(_("Invert")))); _invert_selection.signal_clicked().connect( - mem_fun(this, &MidiMultipleChannelSelector::invert_selection)); - + sigc::mem_fun(this, &MidiMultipleChannelSelector::invert_selection)); + _force_channel.add(*manage(new Label(_("Force")))); _force_channel.signal_toggled().connect( - mem_fun(this, &MidiMultipleChannelSelector::force_channels_button_toggled)); + sigc::mem_fun(this, &MidiMultipleChannelSelector::force_channels_button_toggled)); set_homogeneous(false); attach(*manage(new VSeparator()), 4, 5, 0, 4, SHRINK, FILL, 0, 0); @@ -150,7 +177,7 @@ MidiMultipleChannelSelector::MidiMultipleChannelSelector(ChannelMode mode, uint1 attach(_select_none, 5, 6, 1, 2); attach(_invert_selection, 5, 6, 2, 3); attach(_force_channel, 5, 6, 3, 4); - + set_selected_channels(mask); } @@ -160,7 +187,7 @@ MidiMultipleChannelSelector::~MidiMultipleChannelSelector() } void -MidiMultipleChannelSelector::set_channel_mode(ChannelMode mode, uint8_t mask) +MidiMultipleChannelSelector::set_channel_mode(ChannelMode mode, uint16_t mask) { switch (mode) { case AllChannels: @@ -180,21 +207,21 @@ MidiMultipleChannelSelector::set_channel_mode(ChannelMode mode, uint8_t mask) } } -const uint16_t -MidiMultipleChannelSelector::get_selected_channels() const -{ +uint16_t +MidiMultipleChannelSelector::get_selected_channels() const +{ uint16_t selected_channels = 0; for (uint16_t i = 0; i < 16; i++) { const ToggleButton* button = &_buttons[i / 4][i % 4]; if (button->get_active()) { selected_channels |= (1L << i); - } + } } - - return selected_channels; + + return selected_channels; } -void +void MidiMultipleChannelSelector::set_selected_channels(uint16_t selected_channels) { for (uint16_t i = 0; i < 16; i++) { @@ -208,7 +235,7 @@ MidiMultipleChannelSelector::set_selected_channels(uint16_t selected_channels) } void -MidiMultipleChannelSelector::button_toggled(ToggleButton *button, uint8_t channel) +MidiMultipleChannelSelector::button_toggled(ToggleButton */*button*/, uint8_t channel) { ++_recursion_counter; if (_recursion_counter == 1) { @@ -222,7 +249,7 @@ MidiMultipleChannelSelector::button_toggled(ToggleButton *button, uint8_t channe --_recursion_counter; } -void +void MidiMultipleChannelSelector::force_channels_button_toggled() { if (_force_channel.get_active()) { @@ -241,13 +268,13 @@ MidiMultipleChannelSelector::force_channels_button_toggled() found_first_active = true; active_channel = i; } - } + } } - + if (!found_first_active) { _buttons[0][0].set_active(true); } - + _select_all.set_sensitive(false); _select_none.set_sensitive(false); _invert_selection.set_sensitive(false); @@ -261,7 +288,7 @@ MidiMultipleChannelSelector::force_channels_button_toggled() } } -void +void MidiMultipleChannelSelector::select_all(bool on) { if (_channel_mode == ForceChannel) @@ -276,7 +303,7 @@ MidiMultipleChannelSelector::select_all(bool on) mode_changed.emit(_channel_mode, get_selected_channels()); } -void +void MidiMultipleChannelSelector::invert_selection(void) { if (_channel_mode == ForceChannel) @@ -295,3 +322,572 @@ MidiMultipleChannelSelector::invert_selection(void) mode_changed.emit(_channel_mode, get_selected_channels()); } +/*-----------------------------------------*/ + +MidiChannelSelectorWindow::MidiChannelSelectorWindow (boost::shared_ptr mt) + : 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_mode_changed (); + capture_mode_changed (); + + playback_mask_changed (); + capture_mask_changed (); + + track->playback_filter().ChannelMaskChanged.connect (*this, MISSING_INVALIDATOR, boost::bind (&MidiChannelSelectorWindow::playback_mask_changed, this), gui_context()); + track->playback_filter().ChannelModeChanged.connect (*this, MISSING_INVALIDATOR, boost::bind (&MidiChannelSelectorWindow::playback_mode_changed, this), gui_context()); + track->capture_filter().ChannelMaskChanged.connect (*this, MISSING_INVALIDATOR, boost::bind (&MidiChannelSelectorWindow::capture_mask_changed, this), gui_context()); + track->capture_filter().ChannelModeChanged.connect (*this, MISSING_INVALIDATOR, boost::bind (&MidiChannelSelectorWindow::capture_mode_changed, this), gui_context()); +} + +MidiChannelSelectorWindow::~MidiChannelSelectorWindow() +{ +} + +void +MidiChannelSelectorWindow::build () +{ + VBox* vpacker; + HBox* capture_controls; + HBox* playback_controls; + Button* b; + Label* l; + + vpacker = manage (new VBox); + vpacker->set_spacing (6); + vpacker->set_border_width (12); + + l = manage (new Label (string_compose (("%1: %2"), _("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 ("%1", _("Inbound")))); + l->set_use_markup (true); + vpacker->pack_start (*l); + + + 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)); + + 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_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_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_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_controls); + + l = manage (new Label (string_compose ("%1", _("Playback")))); + l->set_use_markup (true); + vpacker->pack_start (*l); + + 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)); + + vpacker->pack_start (playback_mask_box); + + 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_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_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_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_controls); + + add (*vpacker); +} + +void +MidiChannelSelectorWindow::fill_playback_mask () +{ + if (track->get_playback_channel_mode() == FilterChannels) { + track->set_playback_channel_mask (0xffff); + } +} + +void +MidiChannelSelectorWindow::zero_playback_mask () +{ + if (track->get_playback_channel_mode() == FilterChannels) { + track->set_playback_channel_mask (0); + } +} + +void +MidiChannelSelectorWindow::invert_playback_mask () +{ + if (track->get_playback_channel_mode() == FilterChannels) { + track->set_playback_channel_mask (~track->get_playback_channel_mask()); + } +} + +void +MidiChannelSelectorWindow::fill_capture_mask () +{ + if (track->get_capture_channel_mode() == FilterChannels) { + track->set_capture_channel_mask (0xffff); + } +} + +void +MidiChannelSelectorWindow::zero_capture_mask () +{ + if (track->get_capture_channel_mode() == FilterChannels) { + track->set_capture_channel_mask (0); + } +} + +void +MidiChannelSelectorWindow::invert_capture_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) +{ + 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<set_active (i == (PBD::ffs (mask) - 1)); + } + break; + } +} + +void +MidiChannelSelectorWindow::set_capture_selected_channels (uint16_t 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<set_active (i == (PBD::ffs (mask) - 1)); + } + break; + } +} + +void +MidiChannelSelectorWindow::playback_mask_changed () +{ + set_playback_selected_channels (track->get_playback_channel_mask()); +} + +void +MidiChannelSelectorWindow::capture_mask_changed () +{ + set_capture_selected_channels (track->get_capture_channel_mask()); +} + +void +MidiChannelSelectorWindow::playback_mode_changed () +{ + uint32_t first_channel = 0; + ChannelMode mode = track->get_playback_channel_mode(); + + switch (mode) { + case AllChannels: + 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::iterator i = playback_mask_controls.begin(); i != playback_mask_controls.end(); ++i) { + (*i)->set_sensitive (false); + } + playback_all_button.set_active (); + break; + + case FilterChannels: + if (last_drawn_playback_mode == ForceChannel) { + playback_buttons.clear (); + } else if (last_drawn_playback_mode == AllChannels) { + for (vector::iterator i = playback_buttons.begin(); i != playback_buttons.end(); ++i) { + (*i)->set_sensitive (true); + } + } + for (vector::iterator i = playback_mask_controls.begin(); i != playback_mask_controls.end(); ++i) { + (*i)->set_sensitive (true); + } + playback_filter_button.set_active (); + break; + + case ForceChannel: + if (last_drawn_playback_mode == AllChannels || last_drawn_playback_mode == FilterChannels) { + playback_buttons.clear (); + first_channel = PBD::ffs (track->get_playback_channel_mask()) - 1; + } + for (vector::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::iterator i = playback_buttons.begin(); i != playback_buttons.end(); ++i) { + (*i)->set_sensitive (false); + } + } + + playback_mask_changed(); // update buttons + + last_drawn_playback_mode = mode; +} + +void +MidiChannelSelectorWindow::capture_mode_changed () +{ + uint32_t first_channel = 0; + ChannelMode mode = track->get_capture_channel_mode(); + + switch (mode) { + case AllChannels: + 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::iterator i = capture_mask_controls.begin(); i != capture_mask_controls.end(); ++i) { + (*i)->set_sensitive (false); + } + capture_all_button.set_active (); + break; + + case FilterChannels: + if (last_drawn_capture_mode == ForceChannel) { + capture_buttons.clear (); + } else if (last_drawn_capture_mode == AllChannels) { + for (vector::iterator i = capture_buttons.begin(); i != capture_buttons.end(); ++i) { + (*i)->set_sensitive (true); + } + } + for (vector::iterator i = capture_mask_controls.begin(); i != capture_mask_controls.end(); ++i) { + (*i)->set_sensitive (true); + } + capture_filter_button.set_active (); + break; + + case ForceChannel: + if (last_drawn_capture_mode == AllChannels || last_drawn_capture_mode == FilterChannels) { + capture_buttons.clear (); + first_channel = PBD::ffs (track->get_capture_channel_mask()) - 1; + } + for (vector::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::iterator i = capture_buttons.begin(); i != capture_buttons.end(); ++i) { + (*i)->set_sensitive (false); + } + } + + capture_mask_changed (); // udpate buttons + + last_drawn_capture_mode = mode; +} + +void +MidiChannelSelectorWindow::playback_channel_clicked (uint16_t n) +{ + if (playback_buttons[n]->get_active()) { + switch (track->get_playback_channel_mode()) { + case AllChannels: + break; + case FilterChannels: + track->set_playback_channel_mask (track->get_playback_channel_mask() | (1<set_playback_channel_mask (1<get_playback_channel_mode() == FilterChannels) { + track->set_playback_channel_mask (track->get_playback_channel_mask() & ~(1<get_active()) { + switch (track->get_capture_channel_mode()) { + case AllChannels: + break; + case FilterChannels: + track->set_capture_channel_mask (track->get_capture_channel_mask() | (1<set_capture_channel_mask (1<get_capture_channel_mode() == FilterChannels) { + track->set_capture_channel_mask (track->get_capture_channel_mask() & ~(1<set_capture_channel_mode (AllChannels, track->get_capture_channel_mask()); + } + break; + case FilterChannels: + if (capture_filter_button.get_active()) { + track->set_capture_channel_mode (FilterChannels, track->get_capture_channel_mask()); + } + break; + case ForceChannel: + if (capture_force_button.get_active()) { + track->set_capture_channel_mode (ForceChannel, track->get_capture_channel_mask()); + } + break; + } +} + +void +MidiChannelSelectorWindow::playback_mode_toggled (ChannelMode mode) +{ + /* this is called twice for every radio button change. the first time + 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 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()) { + track->set_playback_channel_mode (AllChannels, track->get_playback_channel_mask()); + } + break; + case FilterChannels: + if (playback_filter_button.get_active()) { + track->set_playback_channel_mode (FilterChannels, track->get_playback_channel_mask()); + } + break; + case ForceChannel: + if (playback_force_button.get_active()) { + track->set_playback_channel_mode (ForceChannel, track->get_playback_channel_mask()); + } + break; + } +} + +void +MidiChannelSelectorWindow::set_channel_colors (const uint32_t new_channel_colors[16]) +{ + for (uint32_t n = 0; n < 16; ++n) { + + char color_normal[8]; + char color_active[8]; + + snprintf(color_normal, 8, "#%x", UINT_INTERPOLATE(new_channel_colors[n], 0x000000ff, 0.6)); + snprintf(color_active, 8, "#%x", new_channel_colors[n]); + + playback_buttons[n]->modify_bg(STATE_NORMAL, Gdk::Color(color_normal)); + playback_buttons[n]->modify_bg(STATE_ACTIVE, Gdk::Color(color_active)); + + capture_buttons[n]->modify_bg(STATE_NORMAL, Gdk::Color(color_normal)); + capture_buttons[n]->modify_bg(STATE_ACTIVE, Gdk::Color(color_active)); + } +} + +void +MidiChannelSelectorWindow::set_default_channel_color() +{ + for (uint32_t n = 0; n < 16; ++n) { + playback_buttons[n]->unset_fg (STATE_NORMAL); + playback_buttons[n]->unset_bg (STATE_NORMAL); + playback_buttons[n]->unset_fg (STATE_ACTIVE); + playback_buttons[n]->unset_bg (STATE_ACTIVE); + + capture_buttons[n]->unset_fg (STATE_NORMAL); + capture_buttons[n]->unset_bg (STATE_NORMAL); + capture_buttons[n]->unset_fg (STATE_ACTIVE); + capture_buttons[n]->unset_bg (STATE_ACTIVE); + } +}