diff options
author | Hans Baier <hansfbaier@googlemail.com> | 2008-12-23 06:03:45 +0000 |
---|---|---|
committer | Hans Baier <hansfbaier@googlemail.com> | 2008-12-23 06:03:45 +0000 |
commit | e9a9fe30cf8661aeb48b5392d5e8f5c3f432b809 (patch) | |
tree | 471dca8335157be6136cbb1f3bcbdf8e2a4eadf7 | |
parent | e6c2f03ca1200381f379da8e84f8068d2901bbaf (diff) |
* added comments to midi_region_view.h
* implemented choosing patches with context menu on the program change flag
* added convenience method and a little refactoring in midi_patch_manager.h
Conflicts:
.cproject
build-tmp.sh
git-svn-id: svn://localhost/ardour2/branches/3.0@4338 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r-- | gtk2_ardour/canvas-program-change.cc | 77 | ||||
-rw-r--r-- | gtk2_ardour/canvas-program-change.h | 33 | ||||
-rw-r--r-- | gtk2_ardour/midi_region_view.cc | 23 | ||||
-rw-r--r-- | gtk2_ardour/midi_region_view.h | 39 | ||||
-rw-r--r-- | libs/ardour/ardour/midi_patch_manager.h | 39 | ||||
-rw-r--r-- | libs/midi++2/midi++/midnam_patch.h | 2 |
6 files changed, 187 insertions, 26 deletions
diff --git a/gtk2_ardour/canvas-program-change.cc b/gtk2_ardour/canvas-program-change.cc index 8c24ce95e3..24f13f2605 100644 --- a/gtk2_ardour/canvas-program-change.cc +++ b/gtk2_ardour/canvas-program-change.cc @@ -1,9 +1,12 @@ -#include "canvas-program-change.h" #include <iostream> + +#include "ardour/midi_patch_manager.h" #include "ardour_ui.h" #include "midi_region_view.h" +#include "canvas-program-change.h" using namespace Gnome::Canvas; +using namespace MIDI::Name; using namespace std; CanvasProgramChange::CanvasProgramChange( @@ -12,7 +15,13 @@ CanvasProgramChange::CanvasProgramChange( string& text, double height, double x, - double y) + double y, + string& model_name, + string& custom_device_mode, + nframes_t event_time, + uint8_t channel, + uint8_t program + ) : CanvasFlag( region, parent, @@ -22,18 +31,80 @@ CanvasProgramChange::CanvasProgramChange( x, y ) + , _model_name(model_name) + , _custom_device_mode(custom_device_mode) + , _event_time(event_time) + , _channel(channel) + , _program(program) { set_text(text); + initialize_popup_menus(); } CanvasProgramChange::~CanvasProgramChange() { } +void +CanvasProgramChange::initialize_popup_menus() +{ + boost::shared_ptr<ChannelNameSet> channel_name_set = + MidiPatchManager::instance() + .find_channel_name_set(_model_name, _custom_device_mode, _channel); + + if (!channel_name_set) { + return; + } + + const ChannelNameSet::PatchBanks& patch_banks = channel_name_set->patch_banks(); + + // fill popup menu: + Gtk::Menu::MenuList& patch_bank_menus = _popup.items(); + + for (ChannelNameSet::PatchBanks::const_iterator bank = patch_banks.begin(); + bank != patch_banks.end(); + ++bank) { + Gtk::Menu& patch_bank_menu = *manage(new Gtk::Menu()); + + const PatchBank::PatchNameList& patches = (*bank)->patch_name_list(); + Gtk::Menu::MenuList& patch_menus = patch_bank_menu.items(); + + for (PatchBank::PatchNameList::const_iterator patch = patches.begin(); + patch != patches.end(); + ++patch) { + patch_menus.push_back( + Gtk::Menu_Helpers::MenuElem( + (*patch)->name(), + sigc::bind( + sigc::mem_fun(*this, &CanvasProgramChange::on_patch_menu_selected), + (*patch)->patch_primary_key())) ); + } + + patch_bank_menus.push_back( + Gtk::Menu_Helpers::MenuElem( + (*bank)->name(), + patch_bank_menu) ); + } +} + +void +CanvasProgramChange::on_patch_menu_selected(const PatchPrimaryKey& key) +{ + cerr << " got patch program number " << key.program_number << endl; + _region.program_selected(*this, key); +} + bool CanvasProgramChange::on_event(GdkEvent* ev) { switch (ev->type) { + case GDK_BUTTON_PRESS: + if (ev->button.button == 3) { + _popup.popup(ev->button.button, ev->button.time); + return true; + } + break; + case GDK_SCROLL: if (ev->scroll.direction == GDK_SCROLL_UP) { _region.previous_program(*this); @@ -42,6 +113,8 @@ CanvasProgramChange::on_event(GdkEvent* ev) _region.next_program(*this); return true; } + break; + default: break; } diff --git a/gtk2_ardour/canvas-program-change.h b/gtk2_ardour/canvas-program-change.h index 2620359036..39c11dc090 100644 --- a/gtk2_ardour/canvas-program-change.h +++ b/gtk2_ardour/canvas-program-change.h @@ -5,6 +5,12 @@ class MidiRegionView; +namespace MIDI { + namespace Name { + struct PatchPrimaryKey; + } +} + namespace Gnome { namespace Canvas { @@ -16,14 +22,25 @@ public: Group& parent, string& text, double height, - double x = 0.0, - double y = 0.0 + double x, + double y, + string& model_name, + string& custom_device_mode, + nframes_t event_time, + uint8_t channel, + uint8_t program ); virtual ~CanvasProgramChange(); virtual bool on_event(GdkEvent* ev); + string model_name() const { return _model_name; } + void set_model_name(string model_name) { _model_name = model_name; } + + string custom_device_mode() const { return _custom_device_mode; } + void set_custom_device_mode(string custom_device_mode) { _custom_device_mode = custom_device_mode; } + nframes_t event_time() const { return _event_time; } void set_event_time(nframes_t new_time) { _event_time = new_time; }; @@ -33,11 +50,17 @@ public: uint8_t channel() const { return _channel; } void set_channel(uint8_t new_channel) { _channel = new_channel; }; + void initialize_popup_menus(); + + void on_patch_menu_selected(const MIDI::Name::PatchPrimaryKey& key); private: - nframes_t _event_time; - uint8_t _program; - uint8_t _channel; + string _model_name; + string _custom_device_mode; + nframes_t _event_time; + uint8_t _channel; + uint8_t _program; + Gtk::Menu _popup; }; } // namespace Canvas diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc index c81edd4e7b..5e80393386 100644 --- a/gtk2_ardour/midi_region_view.cc +++ b/gtk2_ardour/midi_region_view.cc @@ -1005,10 +1005,18 @@ MidiRegionView::add_pgm_change(ControlEvent& program, string displaytext) double height = midi_stream_view()->contents_height(); boost::shared_ptr<CanvasProgramChange> pgm_change = boost::shared_ptr<CanvasProgramChange>( - new CanvasProgramChange(*this, *group, displaytext, height, x, 1.0)); - pgm_change->set_event_time(program.time); - pgm_change->set_program(program.value); - pgm_change->set_channel(program.channel); + new CanvasProgramChange( + *this, + *group, + displaytext, + height, + x, + 1.0, + _model_name, + _custom_device_mode, + program.time, + program.channel, + program.value)); _pgm_changes.push_back(pgm_change); } @@ -1076,6 +1084,13 @@ MidiRegionView::alter_program_change(ControlEvent& old_program, const MIDI::Name redisplay_model(); } +void +MidiRegionView::program_selected(CanvasProgramChange& program, const MIDI::Name::PatchPrimaryKey& new_patch) +{ + ControlEvent program_change_event(program.event_time(), program.program(), program.channel()); + alter_program_change(program_change_event, new_patch); +} + void MidiRegionView::previous_program(CanvasProgramChange& program) { diff --git a/gtk2_ardour/midi_region_view.h b/gtk2_ardour/midi_region_view.h index ca4a43f962..d920a84ca0 100644 --- a/gtk2_ardour/midi_region_view.h +++ b/gtk2_ardour/midi_region_view.h @@ -109,11 +109,50 @@ class MidiRegionView : public RegionView } }; + /** + * Adds a new program change flag to the canvas + * @param program the MidiRegionView::ControlEvent to add + * @param the text to display in the flag + */ void add_pgm_change(ControlEvent& program, string displaytext); + + /** + * Looks up in the automation list in the specified time and channel and sets keys + * fields accordingly + * @param time the time of the program change event + * @param channel the MIDI channel of the event + * @key a reference to an instance of MIDI::Name::PatchPrimaryKey whose fields will + * will be set according to the result of the lookup + */ void get_patch_key_at(double time, uint8_t channel, MIDI::Name::PatchPrimaryKey& key); + + /** + * changes the automation list data of old_program to the new values which correspond to new_patch + * @param old_program identifies the program change event which is to be altered + * @param new_patch defines the new lsb, msb and program number which are to be set in the automation list data + */ void alter_program_change(ControlEvent& old_program, const MIDI::Name::PatchPrimaryKey& new_patch); + + /** + * alters a given program to the new given one (called on context menu select on CanvasProgramChange) + */ + void program_selected( + ArdourCanvas::CanvasProgramChange& program, + const MIDI::Name::PatchPrimaryKey& new_patch); + + /** + * alters a given program to be its predecessor in the MIDNAM file + */ void previous_program(ArdourCanvas::CanvasProgramChange& program); + + /** + * alters a given program to be its successor in the MIDNAM file + */ void next_program(ArdourCanvas::CanvasProgramChange& program); + + /** + * displays all program changed events in the region as flags on the canvas + */ void find_and_insert_program_change_flags(); void begin_write(); diff --git a/libs/ardour/ardour/midi_patch_manager.h b/libs/ardour/ardour/midi_patch_manager.h index f617d82998..10d0f99a7a 100644 --- a/libs/ardour/ardour/midi_patch_manager.h +++ b/libs/ardour/ardour/midi_patch_manager.h @@ -63,18 +63,31 @@ public: boost::shared_ptr<MasterDeviceNames> master_device_by_model(std::string model_name) { return _master_devices_by_model[model_name]; } + boost::shared_ptr<ChannelNameSet> find_channel_name_set( + string model, + string custom_device_mode, + uint8_t channel) { + boost::shared_ptr<MIDI::Name::MasterDeviceNames> master_device = master_device_by_model(model); + + if (master_device != 0 && custom_device_mode != "") { + return master_device-> + channel_name_set_by_device_mode_and_channel(custom_device_mode, channel); + } else { + return boost::shared_ptr<ChannelNameSet>(); + } + } + + boost::shared_ptr<Patch> find_patch( string model, string custom_device_mode, uint8_t channel, PatchPrimaryKey patch_key) { - boost::shared_ptr<MIDI::Name::MasterDeviceNames> master_device = master_device_by_model(model); + boost::shared_ptr<ChannelNameSet> channel_name_set = find_channel_name_set(model, custom_device_mode, channel); - if (master_device != 0 && custom_device_mode != "") { - return master_device-> - channel_name_set_by_device_mode_and_channel(custom_device_mode, channel)-> - find_patch(patch_key); + if (channel_name_set) { + return channel_name_set->find_patch(patch_key); } else { return boost::shared_ptr<Patch>(); } @@ -86,12 +99,10 @@ public: uint8_t channel, PatchPrimaryKey patch_key) { - boost::shared_ptr<MIDI::Name::MasterDeviceNames> master_device = master_device_by_model(model); + boost::shared_ptr<ChannelNameSet> channel_name_set = find_channel_name_set(model, custom_device_mode, channel); - if (master_device != 0 && custom_device_mode != "") { - return master_device-> - channel_name_set_by_device_mode_and_channel(custom_device_mode, channel)-> - previous_patch(patch_key); + if (channel_name_set) { + return channel_name_set->previous_patch(patch_key); } else { return boost::shared_ptr<Patch>(); } @@ -103,12 +114,10 @@ public: uint8_t channel, PatchPrimaryKey patch_key) { - boost::shared_ptr<MIDI::Name::MasterDeviceNames> master_device = master_device_by_model(model); + boost::shared_ptr<ChannelNameSet> channel_name_set = find_channel_name_set(model, custom_device_mode, channel); - if (master_device != 0 && custom_device_mode != "") { - return master_device-> - channel_name_set_by_device_mode_and_channel(custom_device_mode, channel)-> - next_patch(patch_key); + if (channel_name_set) { + return channel_name_set->next_patch(patch_key); } else { return boost::shared_ptr<Patch>(); } diff --git a/libs/midi++2/midi++/midnam_patch.h b/libs/midi++2/midi++/midnam_patch.h index 24838294ec..265511e50c 100644 --- a/libs/midi++2/midi++/midnam_patch.h +++ b/libs/midi++2/midi++/midnam_patch.h @@ -149,6 +149,8 @@ public: const string& name() const { return _name; } void set_name(const string a_name) { _name = a_name; } + + const PatchBanks& patch_banks() const { return _patch_banks; } bool available_for_channel(uint8_t channel) const { return _available_for_channels.find(channel) != _available_for_channels.end(); |