+/*
+ 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 <sstream>
#include "midi_channel_selector.h"
#include "gtkmm/separator.h"
#include "i18n.h"
-#include <sstream>
+#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());
{
}
+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
--_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(
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);
}
}
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);
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;
}
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());
}