X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Fmidi_channel_selector.cc;h=12eea5bb12efb1913e3f4704e91b70e6431cda28;hb=3bc71af0ca89354670243e600c70374bfb224c6d;hp=b810268633234e07a12f60f2b3edabff59163065;hpb=f31abc5eaf30ea9ed099279cbc2b7c41c131acd6;p=ardour.git diff --git a/gtk2_ardour/midi_channel_selector.cc b/gtk2_ardour/midi_channel_selector.cc index b810268633..12eea5bb12 100644 --- a/gtk2_ardour/midi_channel_selector.cc +++ b/gtk2_ardour/midi_channel_selector.cc @@ -1,26 +1,48 @@ +/* + Copyright (C) 2008 Paul Davis + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include #include "midi_channel_selector.h" #include "gtkmm/separator.h" #include "i18n.h" -#include +#include "rgb_macros.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) +MidiChannelSelector::MidiChannelSelector(int n_rows, int n_columns, int start_row, int start_column) + : Table(n_rows, n_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); + assert(n_rows >= 4); + assert(n_rows >= start_row + 4); + assert(n_columns >=4); + assert(n_columns >= start_column + 4); 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) { + for (int row = 0; row < 4; ++row) { + for (int column = 0; column < 4; ++column) { ostringstream channel; channel << int(++channel_nr); _button_labels[row][column].set_text(channel.str()); @@ -43,28 +65,55 @@ MidiChannelSelector::~MidiChannelSelector() { } +void +MidiChannelSelector::set_channel_colors(const uint32_t new_channel_colors[16]) +{ + for (int row = 0; row < 4; ++row) { + for (int column = 0; column < 4; ++column) { + char color_normal[8]; + char color_active[8]; + snprintf(color_normal, 8, "#%x", UINT_INTERPOLATE(new_channel_colors[row * 4 + column], 0x000000ff, 0.6)); + snprintf(color_active, 8, "#%x", new_channel_colors[row * 4 + column]); + _buttons[row][column].modify_bg(STATE_NORMAL, Gdk::Color(color_normal)); + _buttons[row][column].modify_bg(STATE_ACTIVE, Gdk::Color(color_active)); + } + } +} + +void +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); + } + } +} + SingleMidiChannelSelector::SingleMidiChannelSelector(uint8_t active_channel) : MidiChannelSelector() { _last_active_button = 0; - ToggleButton *button = &_buttons[active_channel / 4][active_channel % 4]; + ToggleButton* button = &_buttons[active_channel / 4][active_channel % 4]; _active_channel = active_channel; button->set_active(true); _last_active_button = button; } void -SingleMidiChannelSelector::button_toggled(ToggleButton *button, uint8_t channel) +SingleMidiChannelSelector::button_toggled(ToggleButton* button, uint8_t channel) { ++_recursion_counter; - if(_recursion_counter == 1) { + if (_recursion_counter == 1) { // if the current button is active it must // be different from the first one - if(button->get_active()) { - if(_last_active_button) { + if (button->get_active()) { + if (_last_active_button) { _last_active_button->set_active(false); _active_channel = channel; _last_active_button = button; + channel_selected.emit(channel); } } else { // if not, the user pressed the already active button @@ -75,8 +124,9 @@ SingleMidiChannelSelector::button_toggled(ToggleButton *button, uint8_t channel) --_recursion_counter; } -MidiMultipleChannelSelector::MidiMultipleChannelSelector(uint16_t initial_selection) - : MidiChannelSelector(4, 6, 0, 0), _mode(FILTERING_MULTIPLE_CHANNELS) +MidiMultipleChannelSelector::MidiMultipleChannelSelector(ChannelMode mode, uint16_t mask) + : MidiChannelSelector(4, 6, 0, 0) + , _channel_mode(mode) { _select_all.add(*manage(new Label(_("All")))); _select_all.signal_clicked().connect( @@ -102,40 +152,42 @@ MidiMultipleChannelSelector::MidiMultipleChannelSelector(uint16_t initial_select attach(_invert_selection, 5, 6, 2, 3); attach(_force_channel, 5, 6, 3, 4); - set_selected_channels(initial_selection); + set_selected_channels(mask); } MidiMultipleChannelSelector::~MidiMultipleChannelSelector() { - selection_changed.clear(); - force_channel_changed.clear(); + mode_changed.clear(); } -const int8_t -MidiMultipleChannelSelector::get_force_channel() const +void +MidiMultipleChannelSelector::set_channel_mode(ChannelMode mode, uint16_t mask) { - if(_mode == FORCING_SINGLE_CHANNEL) { - for(int8_t i = 0; i < 16; i++) { - const ToggleButton *button = &_buttons[i / 4][i % 4]; - if(button->get_active()) { - return i; - } + switch (mode) { + case AllChannels: + _force_channel.set_active(false); + set_selected_channels(0xFFFF); + break; + case FilterChannels: + _force_channel.set_active(false); + set_selected_channels(mask); + break; + case ForceChannel: + _force_channel.set_active(true); + for (uint16_t i = 0; i < 16; i++) { + ToggleButton* button = &_buttons[i / 4][i % 4]; + button->set_active(i == mask); } - - // this point should not be reached. - assert(false); - } - - return -1; + } } 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()) { + for (uint16_t i = 0; i < 16; i++) { + const ToggleButton* button = &_buttons[i / 4][i % 4]; + if (button->get_active()) { selected_channels |= (1L << i); } } @@ -146,9 +198,9 @@ MidiMultipleChannelSelector::get_selected_channels() const void MidiMultipleChannelSelector::set_selected_channels(uint16_t selected_channels) { - for(uint16_t i = 0; i < 16; i++) { - ToggleButton *button = &_buttons[i / 4][i % 4]; - if(selected_channels & (1L << i)) { + for (uint16_t i = 0; i < 16; i++) { + ToggleButton* button = &_buttons[i / 4][i % 4]; + if (selected_channels & (1L << i)) { button->set_active(true); } else { button->set_active(false); @@ -160,13 +212,13 @@ void MidiMultipleChannelSelector::button_toggled(ToggleButton *button, uint8_t channel) { ++_recursion_counter; - if(_recursion_counter == 1) { - if(_mode == FORCING_SINGLE_CHANNEL) { + if (_recursion_counter == 1) { + if (_channel_mode == ForceChannel) { + mode_changed.emit(_channel_mode, channel); set_selected_channels(1 << channel); + } else { + mode_changed.emit(_channel_mode, get_selected_channels()); } - - force_channel_changed.emit(get_force_channel()); - selection_changed.emit(get_selected_channels()); } --_recursion_counter; } @@ -174,67 +226,73 @@ MidiMultipleChannelSelector::button_toggled(ToggleButton *button, uint8_t channe void MidiMultipleChannelSelector::force_channels_button_toggled() { - if(_force_channel.get_active()) { - _mode = FORCING_SINGLE_CHANNEL; + if (_force_channel.get_active()) { + _channel_mode = ForceChannel; bool found_first_active = false; // leave only the first button enabled - for(int i = 0; i <= 15; i++) { - ToggleButton *button = &_buttons[i / 4][i % 4]; - if(button->get_active()) { - if(found_first_active) { + uint16_t active_channel = 0; + for (int i = 0; i <= 15; i++) { + ToggleButton* button = &_buttons[i / 4][i % 4]; + if (button->get_active()) { + if (found_first_active) { ++_recursion_counter; button->set_active(false); --_recursion_counter; } else { found_first_active = true; + active_channel = i; } } } - if(!found_first_active) { + 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); - force_channel_changed.emit(get_force_channel()); - selection_changed.emit(get_selected_channels()); + mode_changed.emit(_channel_mode, active_channel); } else { - _mode = FILTERING_MULTIPLE_CHANNELS; + _channel_mode = FilterChannels; _select_all.set_sensitive(true); _select_none.set_sensitive(true); _invert_selection.set_sensitive(true); - force_channel_changed.emit(get_force_channel()); - selection_changed.emit(get_selected_channels()); + mode_changed.emit(FilterChannels, get_selected_channels()); } } void MidiMultipleChannelSelector::select_all(bool on) { + if (_channel_mode == ForceChannel) + return; + ++_recursion_counter; - for(uint16_t i = 0; i < 16; i++) { - ToggleButton *button = &_buttons[i / 4][i % 4]; + for (uint16_t i = 0; i < 16; i++) { + ToggleButton* button = &_buttons[i / 4][i % 4]; button->set_active(on); } --_recursion_counter; - selection_changed.emit(get_selected_channels()); + mode_changed.emit(_channel_mode, get_selected_channels()); } void MidiMultipleChannelSelector::invert_selection(void) { + if (_channel_mode == ForceChannel) + return; + ++_recursion_counter; - for(uint16_t i = 0; i < 16; i++) { - ToggleButton *button = &_buttons[i / 4][i % 4]; - if(button->get_active()) { + for (uint16_t i = 0; i < 16; i++) { + ToggleButton* button = &_buttons[i / 4][i % 4]; + if (button->get_active()) { button->set_active(false); } else { button->set_active(true); } } --_recursion_counter; - selection_changed.emit(get_selected_channels()); + mode_changed.emit(_channel_mode, get_selected_channels()); }