2 Copyright (C) 2008-2013 Paul Davis
3 Original Author: Hans Baier
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include <gtkmm/separator.h>
23 #include <gtkmm/box.h>
24 #include <gtkmm/label.h>
25 #include <gtkmm/togglebutton.h>
26 #include <gtkmm/radiobutton.h>
27 #include <gtkmm/table.h>
29 #include "pbd/compose.h"
31 #include "gtkmm2ext/gtk_ui.h"
32 #include "gtkmm2ext/gui_thread.h"
33 #include "gtkmm2ext/utils.h"
35 #include "ardour/midi_track.h"
37 #include "midi_channel_selector.h"
38 #include "rgb_macros.h"
44 using namespace ARDOUR;
46 MidiChannelSelector::MidiChannelSelector(int n_rows, int n_columns, int start_row, int start_column)
47 : Table(n_rows, n_columns, true)
48 , _recursion_counter(0)
50 n_rows = std::max(4, n_rows);
51 n_rows = std::max(4, start_row + 4);
52 n_columns = std::max(4, n_columns);
53 n_columns = std::max(4, start_column + 4);
55 property_column_spacing() = 0;
56 property_row_spacing() = 0;
58 uint8_t channel_nr = 0;
59 for (int row = 0; row < 4; ++row) {
60 for (int column = 0; column < 4; ++column) {
61 ostringstream channel;
62 channel << int(++channel_nr);
63 _button_labels[row][column].set_text(channel.str());
64 _button_labels[row][column].set_justify(JUSTIFY_RIGHT);
65 _buttons[row][column].add(_button_labels[row][column]);
66 _buttons[row][column].signal_toggled().connect(
68 sigc::mem_fun(this, &MidiChannelSelector::button_toggled),
69 &_buttons[row][column],
71 _buttons[row][column].set_widget_name (X_("MidiChannelSelectorButton"));
73 _buttons[row][column].signal_button_release_event().connect(
74 sigc::mem_fun(this, &MidiChannelSelector::was_clicked), false);
76 int table_row = start_row + row;
77 int table_column = start_column + column;
78 attach(_buttons[row][column], table_column, table_column + 1, table_row, table_row + 1);
83 MidiChannelSelector::~MidiChannelSelector()
88 MidiChannelSelector::was_clicked (GdkEventButton*)
95 MidiChannelSelector::set_channel_colors(const uint32_t new_channel_colors[16])
97 for (int row = 0; row < 4; ++row) {
98 for (int column = 0; column < 4; ++column) {
100 char color_active[8];
101 snprintf(color_normal, 8, "#%x", UINT_INTERPOLATE(new_channel_colors[row * 4 + column], 0x000000ff, 0.6));
102 snprintf(color_active, 8, "#%x", new_channel_colors[row * 4 + column]);
103 _buttons[row][column].modify_bg(STATE_NORMAL, Gdk::Color(color_normal));
104 _buttons[row][column].modify_bg(STATE_ACTIVE, Gdk::Color(color_active));
110 MidiChannelSelector::set_default_channel_color()
112 for (int row = 0; row < 4; ++row) {
113 for (int column = 0; column < 4; ++column) {
114 _buttons[row][column].unset_fg (STATE_NORMAL);
115 _buttons[row][column].unset_fg (STATE_ACTIVE);
116 _buttons[row][column].unset_bg (STATE_NORMAL);
117 _buttons[row][column].unset_bg (STATE_ACTIVE);
122 SingleMidiChannelSelector::SingleMidiChannelSelector(uint8_t active_channel)
123 : MidiChannelSelector()
125 _last_active_button = 0;
126 ToggleButton* button = &_buttons[active_channel / 4][active_channel % 4];
127 _active_channel = active_channel;
128 button->set_active(true);
129 _last_active_button = button;
133 SingleMidiChannelSelector::button_toggled(ToggleButton* button, uint8_t channel)
135 ++_recursion_counter;
136 if (_recursion_counter == 1) {
137 // if the current button is active it must
138 // be different from the first one
139 if (button->get_active()) {
140 if (_last_active_button) {
141 _last_active_button->set_active(false);
142 _active_channel = channel;
143 _last_active_button = button;
144 channel_selected.emit(channel);
147 // if not, the user pressed the already active button
148 button->set_active(true);
149 _active_channel = channel;
152 --_recursion_counter;
155 MidiMultipleChannelSelector::MidiMultipleChannelSelector(ChannelMode mode, uint16_t mask)
156 : MidiChannelSelector(4, 6, 0, 0)
157 , _channel_mode(mode)
159 _select_all.add(*manage(new Label(_("All"))));
160 _select_all.signal_clicked().connect(
161 sigc::bind(sigc::mem_fun(this, &MidiMultipleChannelSelector::select_all), true));
163 _select_none.add(*manage(new Label(_("None"))));
164 _select_none.signal_clicked().connect(
165 sigc::bind(sigc::mem_fun(this, &MidiMultipleChannelSelector::select_all), false));
167 _invert_selection.add(*manage(new Label(_("Invert"))));
168 _invert_selection.signal_clicked().connect(
169 sigc::mem_fun(this, &MidiMultipleChannelSelector::invert_selection));
171 _force_channel.add(*manage(new Label(_("Force"))));
172 _force_channel.signal_toggled().connect(
173 sigc::mem_fun(this, &MidiMultipleChannelSelector::force_channels_button_toggled));
175 set_homogeneous(false);
176 attach(*manage(new VSeparator()), 4, 5, 0, 4, SHRINK, FILL, 0, 0);
177 //set_row_spacing(4, -5);
178 attach(_select_all, 5, 6, 0, 1);
179 attach(_select_none, 5, 6, 1, 2);
180 attach(_invert_selection, 5, 6, 2, 3);
181 attach(_force_channel, 5, 6, 3, 4);
183 set_selected_channels(mask);
186 MidiMultipleChannelSelector::~MidiMultipleChannelSelector()
188 mode_changed.clear();
192 MidiMultipleChannelSelector::set_channel_mode(ChannelMode mode, uint16_t mask)
196 _force_channel.set_active(false);
197 set_selected_channels(0xFFFF);
200 _force_channel.set_active(false);
201 set_selected_channels(mask);
204 _force_channel.set_active(true);
205 for (uint16_t i = 0; i < 16; i++) {
206 ToggleButton* button = &_buttons[i / 4][i % 4];
207 button->set_active(i == mask);
213 MidiMultipleChannelSelector::get_selected_channels() const
215 uint16_t selected_channels = 0;
216 for (uint16_t i = 0; i < 16; i++) {
217 const ToggleButton* button = &_buttons[i / 4][i % 4];
218 if (button->get_active()) {
219 selected_channels |= (1L << i);
223 return selected_channels;
227 MidiMultipleChannelSelector::set_selected_channels(uint16_t selected_channels)
229 for (uint16_t i = 0; i < 16; i++) {
230 ToggleButton* button = &_buttons[i / 4][i % 4];
231 if (selected_channels & (1L << i)) {
232 button->set_active(true);
234 button->set_active(false);
240 MidiMultipleChannelSelector::button_toggled(ToggleButton */*button*/, uint8_t channel)
242 ++_recursion_counter;
243 if (_recursion_counter == 1) {
244 if (_channel_mode == ForceChannel) {
245 mode_changed.emit(_channel_mode, channel);
246 set_selected_channels(1 << channel);
248 mode_changed.emit(_channel_mode, get_selected_channels());
251 --_recursion_counter;
255 MidiMultipleChannelSelector::force_channels_button_toggled()
257 if (_force_channel.get_active()) {
258 _channel_mode = ForceChannel;
259 bool found_first_active = false;
260 // leave only the first button enabled
261 uint16_t active_channel = 0;
262 for (int i = 0; i <= 15; i++) {
263 ToggleButton* button = &_buttons[i / 4][i % 4];
264 if (button->get_active()) {
265 if (found_first_active) {
266 ++_recursion_counter;
267 button->set_active(false);
268 --_recursion_counter;
270 found_first_active = true;
276 if (!found_first_active) {
277 _buttons[0][0].set_active(true);
280 _select_all.set_sensitive(false);
281 _select_none.set_sensitive(false);
282 _invert_selection.set_sensitive(false);
283 mode_changed.emit(_channel_mode, active_channel);
285 _channel_mode = FilterChannels;
286 _select_all.set_sensitive(true);
287 _select_none.set_sensitive(true);
288 _invert_selection.set_sensitive(true);
289 mode_changed.emit(FilterChannels, get_selected_channels());
294 MidiMultipleChannelSelector::select_all(bool on)
296 if (_channel_mode == ForceChannel)
299 ++_recursion_counter;
300 for (uint16_t i = 0; i < 16; i++) {
301 ToggleButton* button = &_buttons[i / 4][i % 4];
302 button->set_active(on);
304 --_recursion_counter;
305 mode_changed.emit(_channel_mode, get_selected_channels());
309 MidiMultipleChannelSelector::invert_selection(void)
311 if (_channel_mode == ForceChannel)
314 ++_recursion_counter;
315 for (uint16_t i = 0; i < 16; i++) {
316 ToggleButton* button = &_buttons[i / 4][i % 4];
317 if (button->get_active()) {
318 button->set_active(false);
320 button->set_active(true);
323 --_recursion_counter;
324 mode_changed.emit(_channel_mode, get_selected_channels());
327 /*-----------------------------------------*/
329 MidiChannelSelectorWindow::MidiChannelSelectorWindow (boost::shared_ptr<MidiTrack> mt)
330 : ArdourWindow (_("MIDI Channel Control"))
332 , playback_all_button (playback_button_group, _("Playback all channels"))
333 , playback_filter_button (playback_button_group, _("Play only selected channels"))
334 , playback_force_button (playback_button_group, _("Use a single fixed channel for all playback"))
335 , capture_all_button (capture_button_group, _("Record all channels"))
336 , capture_filter_button (capture_button_group, _("Record only selected channels"))
337 , capture_force_button (capture_button_group, _("Force all channels to 1 channel"))
338 , last_drawn_capture_mode (AllChannels)
339 , last_drawn_playback_mode (AllChannels)
343 playback_mode_changed ();
344 capture_mode_changed ();
346 playback_mask_changed ();
347 capture_mask_changed ();
349 track->PlaybackChannelMaskChanged.connect (*this, MISSING_INVALIDATOR, boost::bind (&MidiChannelSelectorWindow::playback_mask_changed, this), gui_context());
350 track->PlaybackChannelModeChanged.connect (*this, MISSING_INVALIDATOR, boost::bind (&MidiChannelSelectorWindow::playback_mode_changed, this), gui_context());
351 track->CaptureChannelMaskChanged.connect (*this, MISSING_INVALIDATOR, boost::bind (&MidiChannelSelectorWindow::capture_mask_changed, this), gui_context());
352 track->CaptureChannelModeChanged.connect (*this, MISSING_INVALIDATOR, boost::bind (&MidiChannelSelectorWindow::capture_mode_changed, this), gui_context());
355 MidiChannelSelectorWindow::~MidiChannelSelectorWindow()
360 MidiChannelSelectorWindow::build ()
363 HBox* capture_controls;
364 HBox* playback_controls;
368 vpacker = manage (new VBox);
369 vpacker->set_spacing (6);
370 vpacker->set_border_width (12);
372 l = manage (new Label (string_compose (("<span size=\"larger\" weight=\"bold\">%1: %2</span>"), _("MIDI Channel Control"), track->name())));
373 l->set_use_markup (true);
374 l->set_alignment (0.5, 0.0);
376 vpacker->pack_start (*l, true, true);
378 l = manage (new Label (string_compose ("<span size=\"large\" weight=\"bold\">%1</span>", _("Inbound"))));
379 l->set_use_markup (true);
380 vpacker->pack_start (*l);
383 vpacker->pack_start (capture_all_button);
384 capture_all_button.signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiChannelSelectorWindow::capture_mode_toggled), AllChannels));
386 vpacker->pack_start (capture_filter_button);
387 capture_filter_button.signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiChannelSelectorWindow::capture_mode_toggled), FilterChannels));
389 vpacker->pack_start (capture_force_button);
390 capture_force_button.signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiChannelSelectorWindow::capture_mode_toggled), ForceChannel));
392 vpacker->pack_start (capture_mask_box);
394 capture_controls = manage (new HBox);
395 capture_controls->set_spacing (6);
397 b = manage (new Button (_("All")));
398 Gtkmm2ext::UI::instance()->set_tip (*b, _("Click to enable recording all channels"));
399 capture_controls->pack_start (*b);
400 capture_mask_controls.push_back (b);
401 b->signal_clicked().connect (sigc::mem_fun (*this, &MidiChannelSelectorWindow::fill_capture_mask));
402 b = manage (new Button (_("None")));
403 Gtkmm2ext::UI::instance()->set_tip (*b, _("Click to disable recording all channels"));
404 capture_controls->pack_start (*b);
405 capture_mask_controls.push_back (b);
406 b->signal_clicked().connect (sigc::mem_fun (*this, &MidiChannelSelectorWindow::zero_capture_mask));
407 b = manage (new Button (_("Invert")));
408 Gtkmm2ext::UI::instance()->set_tip (*b, _("Click to invert currently selected recording channels"));
409 capture_controls->pack_start (*b);
410 capture_mask_controls.push_back (b);
411 b->signal_clicked().connect (sigc::mem_fun (*this, &MidiChannelSelectorWindow::invert_capture_mask));
413 vpacker->pack_start (*capture_controls);
415 l = manage (new Label (string_compose ("<span size=\"large\" weight=\"bold\">%1</span>", _("Playback"))));
416 l->set_use_markup (true);
417 vpacker->pack_start (*l);
419 vpacker->pack_start (playback_all_button);
420 playback_all_button.signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiChannelSelectorWindow::playback_mode_toggled), AllChannels));
422 vpacker->pack_start (playback_filter_button);
423 playback_filter_button.signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiChannelSelectorWindow::playback_mode_toggled), FilterChannels));
425 vpacker->pack_start (playback_force_button);
426 playback_force_button.signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiChannelSelectorWindow::playback_mode_toggled), ForceChannel));
428 vpacker->pack_start (playback_mask_box);
430 playback_controls = manage (new HBox);
431 playback_controls->set_spacing (6);
433 b = manage (new Button (_("All")));
434 Gtkmm2ext::UI::instance()->set_tip (*b, _("Click to enable playback of all channels"));
435 playback_controls->pack_start (*b);
436 playback_mask_controls.push_back (b);
437 b->signal_clicked().connect (sigc::mem_fun (*this, &MidiChannelSelectorWindow::fill_playback_mask));
438 b = manage (new Button (_("None")));
439 Gtkmm2ext::UI::instance()->set_tip (*b, _("Click to disable playback of all channels"));
440 playback_controls->pack_start (*b);
441 playback_mask_controls.push_back (b);
442 b->signal_clicked().connect (sigc::mem_fun (*this, &MidiChannelSelectorWindow::zero_playback_mask));
443 b = manage (new Button (_("Invert")));
444 Gtkmm2ext::UI::instance()->set_tip (*b, _("Click to invert current selected playback channels"));
445 playback_controls->pack_start (*b);
446 playback_mask_controls.push_back (b);
447 b->signal_clicked().connect (sigc::mem_fun (*this, &MidiChannelSelectorWindow::invert_playback_mask));
449 vpacker->pack_start (*playback_controls);
455 MidiChannelSelectorWindow::fill_playback_mask ()
457 if (track->get_playback_channel_mode() == FilterChannels) {
458 track->set_playback_channel_mask (0xffff);
463 MidiChannelSelectorWindow::zero_playback_mask ()
465 if (track->get_playback_channel_mode() == FilterChannels) {
466 track->set_playback_channel_mask (0);
471 MidiChannelSelectorWindow::invert_playback_mask ()
473 if (track->get_playback_channel_mode() == FilterChannels) {
474 track->set_playback_channel_mask (~track->get_playback_channel_mask());
479 MidiChannelSelectorWindow::fill_capture_mask ()
481 if (track->get_capture_channel_mode() == FilterChannels) {
482 track->set_capture_channel_mask (0xffff);
487 MidiChannelSelectorWindow::zero_capture_mask ()
489 if (track->get_capture_channel_mode() == FilterChannels) {
490 track->set_capture_channel_mask (0);
495 MidiChannelSelectorWindow::invert_capture_mask ()
497 if (track->get_capture_channel_mode() == FilterChannels) {
498 track->set_capture_channel_mask (~track->get_capture_channel_mask());
503 MidiChannelSelectorWindow::set_playback_selected_channels (uint16_t mask)
505 switch (track->get_playback_channel_mode()) {
507 /* they are insensitive, so we don't care */
511 for (uint16_t i = 0; i < 16; i++) {
512 playback_buttons[i]->set_active ((1<<i) & mask);
517 /* only set the lowest set channel in the mask as active */
518 for (uint16_t i = 0; i < 16; i++) {
519 playback_buttons[i]->set_active (i == (ffs (mask) - 1));
526 MidiChannelSelectorWindow::set_capture_selected_channels (uint16_t mask)
528 switch (track->get_capture_channel_mode()) {
530 /* they are insensitive, so we don't care */
534 for (uint16_t i = 0; i < 16; i++) {
535 capture_buttons[i]->set_active ((1<<i) & mask);
540 /* only set the lowest set channel in the mask as active */
541 for (uint16_t i = 0; i < 16; i++) {
542 capture_buttons[i]->set_active (i == (ffs (mask) - 1));
549 MidiChannelSelectorWindow::playback_mask_changed ()
551 set_playback_selected_channels (track->get_playback_channel_mask());
555 MidiChannelSelectorWindow::capture_mask_changed ()
557 set_capture_selected_channels (track->get_capture_channel_mask());
561 MidiChannelSelectorWindow::playback_mode_changed ()
563 uint32_t first_channel = 0;
564 ChannelMode mode = track->get_playback_channel_mode();
568 if (last_drawn_playback_mode == ForceChannel) {
569 /* force mode used radio buttons. not what we want,
570 * though one could argue that we want no buttons
571 * at since they are insensitive
573 playback_buttons.clear ();
575 for (vector<Widget*>::iterator i = playback_mask_controls.begin(); i != playback_mask_controls.end(); ++i) {
576 (*i)->set_sensitive (false);
578 playback_all_button.set_active ();
582 if (last_drawn_playback_mode == ForceChannel) {
583 playback_buttons.clear ();
584 } else if (last_drawn_playback_mode == AllChannels) {
585 for (vector<ToggleButton*>::iterator i = playback_buttons.begin(); i != playback_buttons.end(); ++i) {
586 (*i)->set_sensitive (true);
589 for (vector<Widget*>::iterator i = playback_mask_controls.begin(); i != playback_mask_controls.end(); ++i) {
590 (*i)->set_sensitive (true);
592 playback_filter_button.set_active ();
596 if (last_drawn_playback_mode == AllChannels || last_drawn_playback_mode == FilterChannels) {
597 playback_buttons.clear ();
598 first_channel = ffs (track->get_playback_channel_mask()) - 1;
600 for (vector<Widget*>::iterator i = playback_mask_controls.begin(); i != playback_mask_controls.end(); ++i) {
601 (*i)->set_sensitive (false);
603 playback_force_button.set_active ();
607 if (playback_buttons.empty()) {
609 Gtkmm2ext::container_clear (playback_mask_box);
612 RadioButtonGroup group;
614 for (uint32_t n = 0; n < 16; ++n) {
616 snprintf (buf, sizeof (buf), "%d", n+1);
621 tb = manage (new ToggleButton (buf));
622 Gtkmm2ext::UI::instance()->set_tip (*tb, string_compose (_("Click to toggle playback of channel %1"), n+1));
625 tb = manage (new RadioButton (group, buf));
626 tb->property_draw_indicator() = false;
627 if (n == first_channel) {
628 tb->set_active (true);
630 Gtkmm2ext::UI::instance()->set_tip (*tb, string_compose (_("Click to force all MIDI channel messages to channel %1"), n+1));
633 playback_buttons.push_back (tb);
634 tb->set_name (X_("MidiChannelSelectorButton"));
635 playback_mask_box.pack_start (*tb);
636 tb->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiChannelSelectorWindow::playback_channel_clicked), n));
639 if (mode == AllChannels) {
640 tb->set_sensitive (false);
644 if (mode != ForceChannel) {
645 set_playback_selected_channels (track->get_playback_channel_mask());
649 if (mode == AllChannels) {
650 for (vector<ToggleButton*>::iterator i = playback_buttons.begin(); i != playback_buttons.end(); ++i) {
651 (*i)->set_sensitive (false);
655 last_drawn_playback_mode = mode;
659 MidiChannelSelectorWindow::capture_mode_changed ()
661 uint32_t first_channel = 0;
662 ChannelMode mode = track->get_capture_channel_mode();
666 if (last_drawn_capture_mode == ForceChannel) {
667 /* force mode used radio buttons. not what we want,
668 * though one could argue that we want no buttons
669 * at since they are insensitive
671 capture_buttons.clear ();
673 for (vector<Widget*>::iterator i = capture_mask_controls.begin(); i != capture_mask_controls.end(); ++i) {
674 (*i)->set_sensitive (false);
676 capture_all_button.set_active ();
680 if (last_drawn_capture_mode == ForceChannel) {
681 capture_buttons.clear ();
682 } else if (last_drawn_capture_mode == AllChannels) {
683 for (vector<ToggleButton*>::iterator i = capture_buttons.begin(); i != capture_buttons.end(); ++i) {
684 (*i)->set_sensitive (true);
687 for (vector<Widget*>::iterator i = capture_mask_controls.begin(); i != capture_mask_controls.end(); ++i) {
688 (*i)->set_sensitive (true);
690 capture_filter_button.set_active ();
694 if (last_drawn_capture_mode == AllChannels || last_drawn_capture_mode == FilterChannels) {
695 capture_buttons.clear ();
696 first_channel = ffs (track->get_capture_channel_mask()) - 1;
698 for (vector<Widget*>::iterator i = capture_mask_controls.begin(); i != capture_mask_controls.end(); ++i) {
699 (*i)->set_sensitive (false);
701 capture_force_button.set_active ();
705 if (capture_buttons.empty()) {
707 Gtkmm2ext::container_clear (capture_mask_box);
710 RadioButtonGroup group;
712 for (uint32_t n = 0; n < 16; ++n) {
714 snprintf (buf, sizeof (buf), "%d", n+1);
719 tb = manage (new ToggleButton (buf));
720 Gtkmm2ext::UI::instance()->set_tip (*tb, string_compose (_("Click to toggle recording of channel %1"), n+1));
723 tb = manage (new RadioButton (group, buf));
724 tb->property_draw_indicator() = false;
725 if (n == first_channel) {
726 tb->set_active (true);
728 Gtkmm2ext::UI::instance()->set_tip (*tb, string_compose (_("Click to force all recorded channels to %1"), n+1));
731 capture_buttons.push_back (tb);
732 tb->set_name (X_("MidiChannelSelectorButton"));
733 capture_mask_box.pack_start (*tb);
734 tb->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiChannelSelectorWindow::capture_channel_clicked), n));
737 if (mode == AllChannels) {
738 tb->set_sensitive (false);
742 if (mode != ForceChannel) {
743 set_capture_selected_channels (track->get_capture_channel_mask());
747 if (mode == AllChannels) {
748 for (vector<ToggleButton*>::iterator i = capture_buttons.begin(); i != capture_buttons.end(); ++i) {
749 (*i)->set_sensitive (false);
753 last_drawn_capture_mode = mode;
757 MidiChannelSelectorWindow::playback_channel_clicked (uint16_t n)
759 if (playback_buttons[n]->get_active()) {
760 switch (track->get_playback_channel_mode()) {
764 track->set_playback_channel_mask (track->get_playback_channel_mask() | (1<<n));
767 track->set_playback_channel_mask (1<<n);
771 if (track->get_playback_channel_mode() == FilterChannels) {
772 track->set_playback_channel_mask (track->get_playback_channel_mask() & ~(1<<n));
778 MidiChannelSelectorWindow::capture_channel_clicked (uint16_t n)
780 if (capture_buttons[n]->get_active()) {
781 switch (track->get_capture_channel_mode()) {
785 track->set_capture_channel_mask (track->get_capture_channel_mask() | (1<<n));
788 track->set_capture_channel_mask (1<<n);
792 if (track->get_capture_channel_mode() == FilterChannels) {
793 track->set_capture_channel_mask (track->get_capture_channel_mask() & ~(1<<n));
799 MidiChannelSelectorWindow::capture_mode_toggled (ChannelMode mode)
801 /* this is called twice for every radio button change. the first time
802 is for the button/mode that has been turned off, and the second is for the
803 button/mode that has been turned on.
805 so we take action only if the button is active (i.e it is the one
811 if (capture_all_button.get_active()) {
812 track->set_capture_channel_mode (AllChannels, track->get_capture_channel_mask());
816 if (capture_filter_button.get_active()) {
817 track->set_capture_channel_mode (FilterChannels, track->get_capture_channel_mask());
821 if (capture_force_button.get_active()) {
822 track->set_capture_channel_mode (ForceChannel, track->get_capture_channel_mask());
829 MidiChannelSelectorWindow::playback_mode_toggled (ChannelMode mode)
831 /* this is called twice for every radio button change. the first time
832 is for the button/mode that has been turned off, and the second is for the
833 button/mode that has been turned on.
835 so we take action only if the button is active (i.e it is the one
841 if (playback_all_button.get_active()) {
842 track->set_playback_channel_mode (AllChannels, track->get_playback_channel_mask());
846 if (playback_filter_button.get_active()) {
847 track->set_playback_channel_mode (FilterChannels, track->get_playback_channel_mask());
851 if (playback_force_button.get_active()) {
852 track->set_playback_channel_mode (ForceChannel, track->get_playback_channel_mask());
859 MidiChannelSelectorWindow::set_channel_colors (const uint32_t new_channel_colors[16])
861 for (uint32_t n = 0; n < 16; ++n) {
863 char color_normal[8];
864 char color_active[8];
866 snprintf(color_normal, 8, "#%x", UINT_INTERPOLATE(new_channel_colors[n], 0x000000ff, 0.6));
867 snprintf(color_active, 8, "#%x", new_channel_colors[n]);
869 playback_buttons[n]->modify_bg(STATE_NORMAL, Gdk::Color(color_normal));
870 playback_buttons[n]->modify_bg(STATE_ACTIVE, Gdk::Color(color_active));
872 capture_buttons[n]->modify_bg(STATE_NORMAL, Gdk::Color(color_normal));
873 capture_buttons[n]->modify_bg(STATE_ACTIVE, Gdk::Color(color_active));
878 MidiChannelSelectorWindow::set_default_channel_color()
880 for (uint32_t n = 0; n < 16; ++n) {
881 playback_buttons[n]->unset_fg (STATE_NORMAL);
882 playback_buttons[n]->unset_bg (STATE_NORMAL);
883 playback_buttons[n]->unset_fg (STATE_ACTIVE);
884 playback_buttons[n]->unset_bg (STATE_ACTIVE);
886 capture_buttons[n]->unset_fg (STATE_NORMAL);
887 capture_buttons[n]->unset_bg (STATE_NORMAL);
888 capture_buttons[n]->unset_fg (STATE_ACTIVE);
889 capture_buttons[n]->unset_bg (STATE_ACTIVE);