* added All/None/Invert Buttons to MidiMultipleChannelSelector
[ardour.git] / gtk2_ardour / midi_channel_selector.cc
1 #include "midi_channel_selector.h"
2 #include "gtkmm/separator.h"
3 #include "i18n.h"
4 #include <sstream>
5
6 using namespace std;
7
8 MidiChannelSelector::MidiChannelSelector(int no_rows, int no_columns, int start_row, int start_column) :
9         Gtk::Table(no_rows, no_columns, true)
10 {       
11         assert(no_rows >= 4);
12         assert(no_rows >= start_row + 4);
13         assert(no_columns >=4);
14         assert(no_columns >= start_column + 4);
15         
16         property_column_spacing() = 0;
17         property_row_spacing() = 0;
18         
19         uint8_t channel_nr = 0;
20         for(int row = 0; row < 4; ++row) {
21                 for(int column = 0; column < 4; ++column) {
22                         ostringstream channel;
23                         channel << int(++channel_nr);
24                         _button_labels[row][column].set_text(channel.str());
25                         _button_labels[row][column].set_justify(Gtk::JUSTIFY_RIGHT);
26                         _buttons[row][column].add(_button_labels[row][column]);
27                         _buttons[row][column].signal_toggled().connect(
28                                 sigc::bind(
29                                         sigc::mem_fun(this, &MidiChannelSelector::button_toggled),
30                                         &_buttons[row][column],
31                                         channel_nr - 1));
32
33                         int table_row    = start_row + row;
34                         int table_column = start_column + column;
35                         attach(_buttons[row][column], table_column, table_column + 1, table_row, table_row + 1);
36                 }
37         }
38 }
39
40 MidiChannelSelector::~MidiChannelSelector()
41 {
42 }
43
44 SingleMidiChannelSelector::SingleMidiChannelSelector(uint8_t active_channel)
45         : MidiChannelSelector()
46 {
47         _active_button = 0;
48         Gtk::ToggleButton *button = &_buttons[active_channel / 4][active_channel % 4];
49         button->set_active(true);
50         _active_button = button;
51         _active_channel = active_channel;
52 }
53
54 void
55 SingleMidiChannelSelector::button_toggled(Gtk::ToggleButton *button, uint8_t channel)
56 {
57         if(button->get_active()) {
58                 if(_active_button) {
59                         _active_button->set_active(false);
60                 }
61                 _active_button = button;
62                 _active_channel = channel;
63                 channel_selected.emit(channel);
64         } 
65 }
66
67 MidiMultipleChannelSelector::MidiMultipleChannelSelector(uint16_t initial_selection)
68         : MidiChannelSelector(6, 4, 0, 0)
69 {
70         _select_all.add(*new Gtk::Label(_("All")));
71         _select_all.signal_clicked().connect(
72                         sigc::bind(sigc::mem_fun(this, &MidiMultipleChannelSelector::select_all), true));
73         
74         _select_none.add(*new Gtk::Label(_("None")));
75         _select_none.signal_clicked().connect(
76                         sigc::bind(sigc::mem_fun(this, &MidiMultipleChannelSelector::select_all), false));
77         
78         _invert_selection.add(*new Gtk::Label(_("Invert")));
79         _invert_selection.signal_clicked().connect(
80                         sigc::mem_fun(this, &MidiMultipleChannelSelector::invert_selection));
81
82         set_homogeneous(false);
83         attach(*new Gtk::HSeparator(), 0, 4, 4, 5, Gtk::FILL, Gtk::SHRINK, 0, 0);
84         set_col_spacing(4, -5);
85         attach(_select_all,       0, 2, 5, 6);
86         attach(_select_none,      2, 4, 5, 6);
87         attach(_invert_selection, 0, 4, 6, 7);
88         
89         _selected_channels = 0;
90         for(uint16_t i = 0; i < 16; i++) {
91                 Gtk::ToggleButton *button = &_buttons[i / 4][i % 4];
92                 if(initial_selection & (1L << i)) {
93                         button->set_active(true);
94                 } else {
95                         button->set_active(false);
96                 }
97         }
98 }
99
100 void
101 MidiMultipleChannelSelector::button_toggled(Gtk::ToggleButton *button, uint8_t channel)
102 {
103         _selected_channels = _selected_channels ^ (1L << channel); 
104 }
105
106 void 
107 MidiMultipleChannelSelector::select_all(bool on)
108 {
109         for(uint16_t i = 0; i < 16; i++) {
110                 Gtk::ToggleButton *button = &_buttons[i / 4][i % 4];
111                 button->set_active(on);
112         }
113 }
114
115 void 
116 MidiMultipleChannelSelector::invert_selection(void)
117 {
118         for(uint16_t i = 0; i < 16; i++) {
119                 Gtk::ToggleButton *button = &_buttons[i / 4][i % 4];
120                 if(button->get_active()) {
121                         button->set_active(false);
122                 } else {
123                         button->set_active(true);
124                 }
125         }
126 }
127