2 Copyright (C) 2010 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 #include <gtkmm/comboboxtext.h>
20 #include <gtkmm/box.h>
21 #include <gtkmm/spinbutton.h>
22 #include <gtkmm/table.h>
23 #include <gtkmm/treeview.h>
24 #include <gtkmm/liststore.h>
25 #include <gtkmm/treestore.h>
26 #include <gtkmm/notebook.h>
27 #include <gtkmm/cellrenderercombo.h>
29 #include "pbd/strsplit.h"
31 #include "gtkmm2ext/utils.h"
32 #include "gtkmm2ext/actions.h"
34 #include "mackie_control_protocol.h"
35 #include "device_info.h"
41 using namespace Mackie;
45 MackieControlProtocol::get_gui () const
48 const_cast<MackieControlProtocol*>(this)->build_gui ();
55 MackieControlProtocol::tear_down_gui ()
57 delete (MackieControlProtocolGUI*) _gui;
61 MackieControlProtocol::build_gui ()
63 _gui = (void *) new MackieControlProtocolGUI (*this);
66 MackieControlProtocolGUI::MackieControlProtocolGUI (MackieControlProtocol& p)
69 set_border_width (12);
71 Gtk::Table* table = Gtk::manage (new Gtk::Table (2, 2));
72 table->set_spacings (4);
74 table->attach (*manage (new Gtk::Label (_("Surface type:"))), 0, 1, 0, 1, AttachOptions(FILL|EXPAND), AttachOptions(0));
75 table->attach (_surface_combo, 1, 2, 0, 1, AttachOptions(FILL|EXPAND), AttachOptions(0));
77 vector<string> surfaces;
79 for (std::map<std::string,DeviceInfo>::iterator i = DeviceInfo::device_info.begin(); i != DeviceInfo::device_info.end(); ++i) {
80 std::cerr << "Dveice known: " << i->first << endl;
81 surfaces.push_back (i->first);
83 Gtkmm2ext::set_popdown_strings (_surface_combo, surfaces);
84 _surface_combo.set_active_text (p.device_info().name());
85 _surface_combo.signal_changed().connect (sigc::mem_fun (*this, &MackieControlProtocolGUI::surface_combo_changed));
87 append_page (*table, _("Device Selection"));
90 /* function key editor */
92 append_page (function_key_scroller, _("Function Keys"));
93 function_key_scroller.add (function_key_editor);
95 rebuild_function_key_editor ();
96 function_key_scroller.show_all();
100 MackieControlProtocolGUI::make_action_renderer (Glib::RefPtr<TreeStore> model, Gtk::TreeModelColumnBase column)
102 CellRendererCombo* renderer = manage (new CellRendererCombo);
103 renderer->property_model() = model;
104 renderer->property_editable() = true;
105 renderer->property_text_column() = 0;
106 renderer->property_has_entry() = false;
107 renderer->signal_edited().connect (sigc::bind (sigc::mem_fun(*this, &MackieControlProtocolGUI::action_changed), column));
113 MackieControlProtocolGUI::rebuild_function_key_editor ()
115 /* build a model of all available actions (needs to be tree structured
119 available_action_model = TreeStore::create (available_action_columns);
121 vector<string> paths;
122 vector<string> labels;
123 vector<string> tooltips;
125 vector<AccelKey> bindings;
126 typedef std::map<string,TreeIter> NodeMap;
130 ActionManager::get_all_actions (labels, paths, tooltips, keys, bindings);
132 vector<string>::iterator k;
133 vector<string>::iterator p;
134 vector<string>::iterator t;
135 vector<string>::iterator l;
137 available_action_model->clear ();
139 for (l = labels.begin(), k = keys.begin(), p = paths.begin(), t = tooltips.begin(); l != labels.end(); ++k, ++p, ++t, ++l) {
142 vector<string> parts;
146 split (*p, parts, '/');
152 //kinda kludgy way to avoid displaying menu items as mappable
153 if ( parts[1] == _("Main_menu") )
155 if ( parts[1] == _("JACK") )
157 if ( parts[1] == _("redirectmenu") )
159 if ( parts[1] == _("Editor_menus") )
161 if ( parts[1] == _("RegionList") )
163 if ( parts[1] == _("ProcessorMenu") )
166 if ((r = nodes.find (parts[1])) == nodes.end()) {
168 /* top level is missing */
171 TreeModel::Row parent;
172 rowp = available_action_model->append();
173 nodes[parts[1]] = rowp;
175 parent[available_action_columns.name] = parts[1];
177 row = *(available_action_model->append (parent.children()));
181 row = *(available_action_model->append ((*r->second)->children()));
185 /* add this action */
188 row[available_action_columns.name] = *t;
190 row[available_action_columns.name] = *l;
193 row[available_action_columns.path] = (*p);
196 function_key_editor.append_column (_("Key"), function_key_columns.name);
200 CellRendererCombo* renderer;
202 renderer = make_action_renderer (available_action_model, function_key_columns.plain);
203 col = manage (new TreeViewColumn (_("Plain"), *renderer));
204 col->add_attribute (renderer->property_text(), function_key_columns.plain);
205 function_key_editor.append_column (*col);
207 renderer = make_action_renderer (available_action_model, function_key_columns.shift);
208 col = manage (new TreeViewColumn (_("Shift"), *renderer));
209 col->add_attribute (renderer->property_text(), function_key_columns.shift);
210 function_key_editor.append_column (*col);
212 renderer = make_action_renderer (available_action_model, function_key_columns.control);
213 col = manage (new TreeViewColumn (_("Control"), *renderer));
214 col->add_attribute (renderer->property_text(), function_key_columns.control);
215 function_key_editor.append_column (*col);
217 renderer = make_action_renderer (available_action_model, function_key_columns.option);
218 col = manage (new TreeViewColumn (_("Option"), *renderer));
219 col->add_attribute (renderer->property_text(), function_key_columns.option);
220 function_key_editor.append_column (*col);
222 renderer = make_action_renderer (available_action_model, function_key_columns.cmdalt);
223 col = manage (new TreeViewColumn (_("Cmd/Alt"), *renderer));
224 col->add_attribute (renderer->property_text(), function_key_columns.cmdalt);
225 function_key_editor.append_column (*col);
227 renderer = make_action_renderer (available_action_model, function_key_columns.shiftcontrol);
228 col = manage (new TreeViewColumn (_("Shift+Control"), *renderer));
229 col->add_attribute (renderer->property_text(), function_key_columns.shiftcontrol);
230 function_key_editor.append_column (*col);
232 /* now fill with data */
234 function_key_model = ListStore::create (function_key_columns);
238 for (uint32_t n = 0; n < 16; ++n) {
240 row = *(function_key_model->append());
241 row[function_key_columns.name] = string_compose ("F%1", n+1);
242 row[function_key_columns.number] = n;
243 row[function_key_columns.control] = "c";
244 row[function_key_columns.option] = "o";
245 row[function_key_columns.shift] = "s";
246 row[function_key_columns.cmdalt] = "ca";
247 row[function_key_columns.shiftcontrol] = "sc";
250 function_key_editor.set_model (function_key_model);
254 MackieControlProtocolGUI::action_changed (const Glib::ustring &sPath, const Glib::ustring &text, TreeModelColumnBase col)
256 Gtk::TreePath path(sPath);
257 Gtk::TreeModel::iterator row = function_key_model->get_iter(path);
259 cerr << sPath << '-' << col.index() << " changed to " << text << endl;
262 (*row).set_value (col.index(), text);
267 MackieControlProtocolGUI::surface_combo_changed ()
269 _cp.set_device (_surface_combo.get_active_text());