summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Baier <hansfbaier@googlemail.com>2008-12-23 06:03:45 +0000
committerHans Baier <hansfbaier@googlemail.com>2008-12-23 06:03:45 +0000
commite9a9fe30cf8661aeb48b5392d5e8f5c3f432b809 (patch)
tree471dca8335157be6136cbb1f3bcbdf8e2a4eadf7
parente6c2f03ca1200381f379da8e84f8068d2901bbaf (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.cc77
-rw-r--r--gtk2_ardour/canvas-program-change.h33
-rw-r--r--gtk2_ardour/midi_region_view.cc23
-rw-r--r--gtk2_ardour/midi_region_view.h39
-rw-r--r--libs/ardour/ardour/midi_patch_manager.h39
-rw-r--r--libs/midi++2/midi++/midnam_patch.h2
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();