mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-10 16:46:35 +01:00
* 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
This commit is contained in:
parent
e6c2f03ca1
commit
e9a9fe30cf
6 changed files with 187 additions and 26 deletions
|
|
@ -1,9 +1,12 @@
|
||||||
#include "canvas-program-change.h"
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "ardour/midi_patch_manager.h"
|
||||||
#include "ardour_ui.h"
|
#include "ardour_ui.h"
|
||||||
#include "midi_region_view.h"
|
#include "midi_region_view.h"
|
||||||
|
#include "canvas-program-change.h"
|
||||||
|
|
||||||
using namespace Gnome::Canvas;
|
using namespace Gnome::Canvas;
|
||||||
|
using namespace MIDI::Name;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
CanvasProgramChange::CanvasProgramChange(
|
CanvasProgramChange::CanvasProgramChange(
|
||||||
|
|
@ -12,7 +15,13 @@ CanvasProgramChange::CanvasProgramChange(
|
||||||
string& text,
|
string& text,
|
||||||
double height,
|
double height,
|
||||||
double x,
|
double x,
|
||||||
double y)
|
double y,
|
||||||
|
string& model_name,
|
||||||
|
string& custom_device_mode,
|
||||||
|
nframes_t event_time,
|
||||||
|
uint8_t channel,
|
||||||
|
uint8_t program
|
||||||
|
)
|
||||||
: CanvasFlag(
|
: CanvasFlag(
|
||||||
region,
|
region,
|
||||||
parent,
|
parent,
|
||||||
|
|
@ -22,18 +31,80 @@ CanvasProgramChange::CanvasProgramChange(
|
||||||
x,
|
x,
|
||||||
y
|
y
|
||||||
)
|
)
|
||||||
|
, _model_name(model_name)
|
||||||
|
, _custom_device_mode(custom_device_mode)
|
||||||
|
, _event_time(event_time)
|
||||||
|
, _channel(channel)
|
||||||
|
, _program(program)
|
||||||
{
|
{
|
||||||
set_text(text);
|
set_text(text);
|
||||||
|
initialize_popup_menus();
|
||||||
}
|
}
|
||||||
|
|
||||||
CanvasProgramChange::~CanvasProgramChange()
|
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
|
bool
|
||||||
CanvasProgramChange::on_event(GdkEvent* ev)
|
CanvasProgramChange::on_event(GdkEvent* ev)
|
||||||
{
|
{
|
||||||
switch (ev->type) {
|
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:
|
case GDK_SCROLL:
|
||||||
if (ev->scroll.direction == GDK_SCROLL_UP) {
|
if (ev->scroll.direction == GDK_SCROLL_UP) {
|
||||||
_region.previous_program(*this);
|
_region.previous_program(*this);
|
||||||
|
|
@ -42,6 +113,8 @@ CanvasProgramChange::on_event(GdkEvent* ev)
|
||||||
_region.next_program(*this);
|
_region.next_program(*this);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,12 @@
|
||||||
|
|
||||||
class MidiRegionView;
|
class MidiRegionView;
|
||||||
|
|
||||||
|
namespace MIDI {
|
||||||
|
namespace Name {
|
||||||
|
struct PatchPrimaryKey;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
namespace Gnome {
|
namespace Gnome {
|
||||||
namespace Canvas {
|
namespace Canvas {
|
||||||
|
|
||||||
|
|
@ -16,14 +22,25 @@ public:
|
||||||
Group& parent,
|
Group& parent,
|
||||||
string& text,
|
string& text,
|
||||||
double height,
|
double height,
|
||||||
double x = 0.0,
|
double x,
|
||||||
double y = 0.0
|
double y,
|
||||||
|
string& model_name,
|
||||||
|
string& custom_device_mode,
|
||||||
|
nframes_t event_time,
|
||||||
|
uint8_t channel,
|
||||||
|
uint8_t program
|
||||||
);
|
);
|
||||||
|
|
||||||
virtual ~CanvasProgramChange();
|
virtual ~CanvasProgramChange();
|
||||||
|
|
||||||
virtual bool on_event(GdkEvent* ev);
|
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; }
|
nframes_t event_time() const { return _event_time; }
|
||||||
void set_event_time(nframes_t new_time) { _event_time = new_time; };
|
void set_event_time(nframes_t new_time) { _event_time = new_time; };
|
||||||
|
|
||||||
|
|
@ -33,11 +50,17 @@ public:
|
||||||
uint8_t channel() const { return _channel; }
|
uint8_t channel() const { return _channel; }
|
||||||
void set_channel(uint8_t new_channel) { _channel = new_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:
|
private:
|
||||||
nframes_t _event_time;
|
string _model_name;
|
||||||
uint8_t _program;
|
string _custom_device_mode;
|
||||||
uint8_t _channel;
|
nframes_t _event_time;
|
||||||
|
uint8_t _channel;
|
||||||
|
uint8_t _program;
|
||||||
|
Gtk::Menu _popup;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Canvas
|
} // namespace Canvas
|
||||||
|
|
|
||||||
|
|
@ -1005,10 +1005,18 @@ MidiRegionView::add_pgm_change(ControlEvent& program, string displaytext)
|
||||||
double height = midi_stream_view()->contents_height();
|
double height = midi_stream_view()->contents_height();
|
||||||
|
|
||||||
boost::shared_ptr<CanvasProgramChange> pgm_change = boost::shared_ptr<CanvasProgramChange>(
|
boost::shared_ptr<CanvasProgramChange> pgm_change = boost::shared_ptr<CanvasProgramChange>(
|
||||||
new CanvasProgramChange(*this, *group, displaytext, height, x, 1.0));
|
new CanvasProgramChange(
|
||||||
pgm_change->set_event_time(program.time);
|
*this,
|
||||||
pgm_change->set_program(program.value);
|
*group,
|
||||||
pgm_change->set_channel(program.channel);
|
displaytext,
|
||||||
|
height,
|
||||||
|
x,
|
||||||
|
1.0,
|
||||||
|
_model_name,
|
||||||
|
_custom_device_mode,
|
||||||
|
program.time,
|
||||||
|
program.channel,
|
||||||
|
program.value));
|
||||||
|
|
||||||
_pgm_changes.push_back(pgm_change);
|
_pgm_changes.push_back(pgm_change);
|
||||||
}
|
}
|
||||||
|
|
@ -1076,6 +1084,13 @@ MidiRegionView::alter_program_change(ControlEvent& old_program, const MIDI::Name
|
||||||
redisplay_model();
|
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
|
void
|
||||||
MidiRegionView::previous_program(CanvasProgramChange& program)
|
MidiRegionView::previous_program(CanvasProgramChange& program)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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);
|
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);
|
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);
|
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);
|
void previous_program(ArdourCanvas::CanvasProgramChange& program);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* alters a given program to be its successor in the MIDNAM file
|
||||||
|
*/
|
||||||
void next_program(ArdourCanvas::CanvasProgramChange& program);
|
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 find_and_insert_program_change_flags();
|
||||||
|
|
||||||
void begin_write();
|
void begin_write();
|
||||||
|
|
|
||||||
|
|
@ -63,18 +63,31 @@ public:
|
||||||
boost::shared_ptr<MasterDeviceNames> master_device_by_model(std::string model_name)
|
boost::shared_ptr<MasterDeviceNames> master_device_by_model(std::string model_name)
|
||||||
{ return _master_devices_by_model[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(
|
boost::shared_ptr<Patch> find_patch(
|
||||||
string model,
|
string model,
|
||||||
string custom_device_mode,
|
string custom_device_mode,
|
||||||
uint8_t channel,
|
uint8_t channel,
|
||||||
PatchPrimaryKey patch_key) {
|
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 != "") {
|
if (channel_name_set) {
|
||||||
return master_device->
|
return channel_name_set->find_patch(patch_key);
|
||||||
channel_name_set_by_device_mode_and_channel(custom_device_mode, channel)->
|
|
||||||
find_patch(patch_key);
|
|
||||||
} else {
|
} else {
|
||||||
return boost::shared_ptr<Patch>();
|
return boost::shared_ptr<Patch>();
|
||||||
}
|
}
|
||||||
|
|
@ -86,12 +99,10 @@ public:
|
||||||
uint8_t channel,
|
uint8_t channel,
|
||||||
PatchPrimaryKey patch_key) {
|
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 != "") {
|
if (channel_name_set) {
|
||||||
return master_device->
|
return channel_name_set->previous_patch(patch_key);
|
||||||
channel_name_set_by_device_mode_and_channel(custom_device_mode, channel)->
|
|
||||||
previous_patch(patch_key);
|
|
||||||
} else {
|
} else {
|
||||||
return boost::shared_ptr<Patch>();
|
return boost::shared_ptr<Patch>();
|
||||||
}
|
}
|
||||||
|
|
@ -103,12 +114,10 @@ public:
|
||||||
uint8_t channel,
|
uint8_t channel,
|
||||||
PatchPrimaryKey patch_key) {
|
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 != "") {
|
if (channel_name_set) {
|
||||||
return master_device->
|
return channel_name_set->next_patch(patch_key);
|
||||||
channel_name_set_by_device_mode_and_channel(custom_device_mode, channel)->
|
|
||||||
next_patch(patch_key);
|
|
||||||
} else {
|
} else {
|
||||||
return boost::shared_ptr<Patch>();
|
return boost::shared_ptr<Patch>();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -149,6 +149,8 @@ public:
|
||||||
|
|
||||||
const string& name() const { return _name; }
|
const string& name() const { return _name; }
|
||||||
void set_name(const string a_name) { _name = a_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 {
|
bool available_for_channel(uint8_t channel) const {
|
||||||
return _available_for_channels.find(channel) != _available_for_channels.end();
|
return _available_for_channels.find(channel) != _available_for_channels.end();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue