24f13f26056f6b0041b49bbfc374cf846f77500f
[ardour.git] / gtk2_ardour / canvas-program-change.cc
1 #include <iostream>
2
3 #include "ardour/midi_patch_manager.h"
4 #include "ardour_ui.h"
5 #include "midi_region_view.h"
6 #include "canvas-program-change.h"
7
8 using namespace Gnome::Canvas;
9 using namespace MIDI::Name;
10 using namespace std;
11
12 CanvasProgramChange::CanvasProgramChange(
13                 MidiRegionView&                       region,
14                 Group&                                parent,
15                 string&                               text,
16                 double                                height,
17                 double                                x,
18                 double                                y,
19                 string&                               model_name,
20                 string&                               custom_device_mode,
21                 nframes_t                             event_time,
22                 uint8_t                               channel,
23                 uint8_t                               program
24                 )
25         : CanvasFlag(
26                         region, 
27                         parent, 
28                         height, 
29                         ARDOUR_UI::config()->canvasvar_MidiProgramChangeOutline.get(), 
30                         ARDOUR_UI::config()->canvasvar_MidiProgramChangeFill.get(),
31                         x,
32                         y
33                 )
34          , _model_name(model_name)
35          , _custom_device_mode(custom_device_mode)
36          , _event_time(event_time)
37          , _channel(channel)
38          , _program(program)
39 {
40         set_text(text);
41         initialize_popup_menus();
42 }
43
44 CanvasProgramChange::~CanvasProgramChange()
45 {
46 }
47
48 void 
49 CanvasProgramChange::initialize_popup_menus()
50 {
51         boost::shared_ptr<ChannelNameSet> channel_name_set = 
52                 MidiPatchManager::instance()
53                         .find_channel_name_set(_model_name, _custom_device_mode, _channel);
54
55         if (!channel_name_set) {
56                 return;
57         }
58         
59         const ChannelNameSet::PatchBanks& patch_banks = channel_name_set->patch_banks();
60         
61         // fill popup menu:
62         Gtk::Menu::MenuList& patch_bank_menus = _popup.items();
63         
64         for (ChannelNameSet::PatchBanks::const_iterator bank = patch_banks.begin();
65              bank != patch_banks.end();
66              ++bank) {
67                 Gtk::Menu& patch_bank_menu = *manage(new Gtk::Menu());
68                 
69                 const PatchBank::PatchNameList& patches = (*bank)->patch_name_list();
70                 Gtk::Menu::MenuList& patch_menus = patch_bank_menu.items();
71                 
72                 for (PatchBank::PatchNameList::const_iterator patch = patches.begin();
73                      patch != patches.end();
74                      ++patch) {
75                         patch_menus.push_back(
76                                 Gtk::Menu_Helpers::MenuElem(
77                                         (*patch)->name(), 
78                                         sigc::bind(
79                                                 sigc::mem_fun(*this, &CanvasProgramChange::on_patch_menu_selected), 
80                                                 (*patch)->patch_primary_key())) );              
81                 }
82                 
83                 patch_bank_menus.push_back( 
84                         Gtk::Menu_Helpers::MenuElem(
85                                 (*bank)->name(), 
86                                 patch_bank_menu) );             
87         }
88 }
89
90 void 
91 CanvasProgramChange::on_patch_menu_selected(const PatchPrimaryKey& key)
92 {
93         cerr << " got patch program number " << key.program_number << endl;
94         _region.program_selected(*this, key);
95 }
96
97 bool
98 CanvasProgramChange::on_event(GdkEvent* ev)
99 {
100         switch (ev->type) {
101         case GDK_BUTTON_PRESS:
102                 if (ev->button.button == 3) {
103                     _popup.popup(ev->button.button, ev->button.time);
104                         return true;
105                 }
106                 break;
107                 
108         case GDK_SCROLL:
109                 if (ev->scroll.direction == GDK_SCROLL_UP) {
110                         _region.previous_program(*this);
111                         return true;
112                 } else if (ev->scroll.direction == GDK_SCROLL_DOWN) {
113                         _region.next_program(*this);
114                         return true;
115                 } 
116                 break;
117                 
118         default:
119                 break;
120         }
121         
122         return false;
123 }