diff --git a/gtk2_ardour/midi_channel_selector.cc b/gtk2_ardour/midi_channel_selector.cc index 327b9d74ae..6fba415389 100644 --- a/gtk2_ardour/midi_channel_selector.cc +++ b/gtk2_ardour/midi_channel_selector.cc @@ -1,11 +1,18 @@ #include "midi_channel_selector.h" +#include "gtkmm/separator.h" +#include "i18n.h" #include using namespace std; -MidiChannelSelector::MidiChannelSelector() : - Gtk::Table(4,4,true) -{ +MidiChannelSelector::MidiChannelSelector(int no_rows, int no_columns, int start_row, int start_column) : + Gtk::Table(no_rows, no_columns, true) +{ + assert(no_rows >= 4); + assert(no_rows >= start_row + 4); + assert(no_columns >=4); + assert(no_columns >= start_column + 4); + property_column_spacing() = 0; property_row_spacing() = 0; @@ -22,7 +29,10 @@ MidiChannelSelector::MidiChannelSelector() : sigc::mem_fun(this, &MidiChannelSelector::button_toggled), &_buttons[row][column], channel_nr - 1)); - attach(_buttons[row][column], column, column + 1, row, row + 1); + + int table_row = start_row + row; + int table_column = start_column + column; + attach(_buttons[row][column], table_column, table_column + 1, table_row, table_row + 1); } } } @@ -54,12 +64,64 @@ SingleMidiChannelSelector::button_toggled(Gtk::ToggleButton *button, uint8_t cha } } +MidiMultipleChannelSelector::MidiMultipleChannelSelector(uint16_t initial_selection) + : MidiChannelSelector(6, 4, 0, 0) +{ + _select_all.add(*new Gtk::Label(_("All"))); + _select_all.signal_clicked().connect( + sigc::bind(sigc::mem_fun(this, &MidiMultipleChannelSelector::select_all), true)); + + _select_none.add(*new Gtk::Label(_("None"))); + _select_none.signal_clicked().connect( + sigc::bind(sigc::mem_fun(this, &MidiMultipleChannelSelector::select_all), false)); + + _invert_selection.add(*new Gtk::Label(_("Invert"))); + _invert_selection.signal_clicked().connect( + sigc::mem_fun(this, &MidiMultipleChannelSelector::invert_selection)); + + set_homogeneous(false); + attach(*new Gtk::HSeparator(), 0, 4, 4, 5, Gtk::FILL, Gtk::SHRINK, 0, 0); + set_col_spacing(4, -5); + attach(_select_all, 0, 2, 5, 6); + attach(_select_none, 2, 4, 5, 6); + attach(_invert_selection, 0, 4, 6, 7); + + _selected_channels = 0; + for(uint16_t i = 0; i < 16; i++) { + Gtk::ToggleButton *button = &_buttons[i / 4][i % 4]; + if(initial_selection & (1L << i)) { + button->set_active(true); + } else { + button->set_active(false); + } + } +} + void MidiMultipleChannelSelector::button_toggled(Gtk::ToggleButton *button, uint8_t channel) { - if(button->get_active()) { - _selected_channels.insert(channel); - } else { - _selected_channels.erase(channel); + _selected_channels = _selected_channels ^ (1L << channel); +} + +void +MidiMultipleChannelSelector::select_all(bool on) +{ + for(uint16_t i = 0; i < 16; i++) { + Gtk::ToggleButton *button = &_buttons[i / 4][i % 4]; + button->set_active(on); } } + +void +MidiMultipleChannelSelector::invert_selection(void) +{ + for(uint16_t i = 0; i < 16; i++) { + Gtk::ToggleButton *button = &_buttons[i / 4][i % 4]; + if(button->get_active()) { + button->set_active(false); + } else { + button->set_active(true); + } + } +} + diff --git a/gtk2_ardour/midi_channel_selector.h b/gtk2_ardour/midi_channel_selector.h index 5060087ea6..5b3e20e859 100644 --- a/gtk2_ardour/midi_channel_selector.h +++ b/gtk2_ardour/midi_channel_selector.h @@ -1,8 +1,10 @@ #ifndef __ardour_ui_midi_channel_selector_h__ #define __ardour_ui_midi_channel_selector_h__ +#include "boost/shared_ptr.hpp" #include "gtkmm/table.h" #include "sigc++/trackable.h" +#include "gtkmm/button.h" #include "gtkmm/togglebutton.h" #include "gtkmm/label.h" #include @@ -10,7 +12,7 @@ class MidiChannelSelector : public Gtk::Table { public: - MidiChannelSelector(); + MidiChannelSelector(int no_rows = 4, int no_columns = 4, int start_row = 0, int start_column = 0); virtual ~MidiChannelSelector() = 0; protected: @@ -38,12 +40,20 @@ protected: class MidiMultipleChannelSelector : public MidiChannelSelector { public: - const std::set& get_selected_channels() const { return _selected_channels; } + MidiMultipleChannelSelector(uint16_t initial_selection = 1); + + const uint16_t get_selected_channels() const { return _selected_channels; } protected: virtual void button_toggled(Gtk::ToggleButton *button, uint8_t button_nr); - std::set _selected_channels; + void select_all(bool on); + void invert_selection(void); + + Gtk::Button _select_all; + Gtk::Button _select_none; + Gtk::Button _invert_selection; + uint16_t _selected_channels; }; #endif /*__ardour_ui_midi_channel_selector_h__*/ diff --git a/gtk2_ardour/processor_box.cc b/gtk2_ardour/processor_box.cc index b2b1c3b538..9ce28d0aa6 100644 --- a/gtk2_ardour/processor_box.cc +++ b/gtk2_ardour/processor_box.cc @@ -352,6 +352,7 @@ Menu * ProcessorBox::build_processor_menu () { processor_menu = dynamic_cast(ActionManager::get_widget("/processormenu") ); + assert(processor_menu != 0); processor_menu->set_name ("ArdourContextMenu"); show_all_children();