2 * Copyright (C) 2016 Robin Gareus <robin@gareus.org>
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 #include "gtkmm2ext/utils.h"
21 #include "lua_script_manager.h"
22 #include "script_selector.h"
27 using namespace ARDOUR;
29 LuaScriptManager::LuaScriptManager ()
30 : ArdourWindow (_("Script Manager"))
31 , _a_set_button (_("Add/Set"))
32 , _a_del_button (_("Remove"))
33 , _a_edit_button (_("Edit"))
34 , _a_call_button (_("Call"))
35 , _c_add_button (_("New Hook"))
36 , _c_del_button (_("Remove"))
38 /* action script page */
39 _a_store = ListStore::create (_a_model);
40 _a_view.set_model (_a_store);
41 _a_view.append_column (_("Action"), _a_model.action);
42 _a_view.append_column (_("Name"), _a_model.name);
43 _a_view.get_column(0)->set_resizable (true);
44 _a_view.get_column(0)->set_expand (true);
45 _a_view.get_column(1)->set_resizable (true);
46 _a_view.get_column(1)->set_expand (true);
48 Gtk::HBox* edit_box = manage (new Gtk::HBox);
49 edit_box->set_spacing(3);
51 edit_box->pack_start (_a_set_button, true, true);
52 edit_box->pack_start (_a_del_button, true, true);
53 edit_box->pack_start (_a_edit_button, true, true);
54 edit_box->pack_start (_a_call_button, true, true);
56 _a_set_button.signal_clicked().connect (sigc::mem_fun(*this, &LuaScriptManager::set_action_btn_clicked));
57 _a_del_button.signal_clicked().connect (sigc::mem_fun(*this, &LuaScriptManager::del_action_btn_clicked));
58 _a_edit_button.signal_clicked().connect (sigc::mem_fun(*this, &LuaScriptManager::edit_action_btn_clicked));
59 _a_call_button.signal_clicked().connect (sigc::mem_fun(*this, &LuaScriptManager::call_action_btn_clicked));
60 _a_view.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &LuaScriptManager::action_selection_changed));
62 LuaInstance::instance()->ActionChanged.connect (sigc::mem_fun (*this, &LuaScriptManager::set_action_script_name));
63 LuaInstance::instance()->SlotChanged.connect (sigc::mem_fun (*this, &LuaScriptManager::set_callback_script_name));
65 Gtk::VBox *vbox = manage (new VBox());
66 vbox->pack_start (_a_view, false, false);
67 vbox->pack_end (*edit_box, false, false);
70 pages.pages ().push_back (Notebook_Helpers::TabElem (*vbox, "Action Scripts"));
72 /* action hooks page */
74 _c_store = ListStore::create (_c_model);
75 _c_view.set_model (_c_store);
76 _c_view.append_column (_("Name"), _c_model.name);
77 _c_view.append_column (_("Signal(s)"), _c_model.signals);
78 _c_view.get_column(0)->set_resizable (true);
79 _c_view.get_column(0)->set_expand (true);
80 _c_view.get_column(1)->set_resizable (true);
81 _c_view.get_column(1)->set_expand (true);
82 Gtk::CellRendererText* r = dynamic_cast<Gtk::CellRendererText*>(_c_view.get_column_cell_renderer (1));
83 r->property_ellipsize () = Pango::ELLIPSIZE_MIDDLE;
85 edit_box = manage (new Gtk::HBox);
86 edit_box->set_spacing(3);
87 edit_box->pack_start (_c_add_button, true, true);
88 edit_box->pack_start (_c_del_button, true, true);
90 _c_add_button.signal_clicked().connect (sigc::mem_fun(*this, &LuaScriptManager::add_callback_btn_clicked));
91 _c_del_button.signal_clicked().connect (sigc::mem_fun(*this, &LuaScriptManager::del_callback_btn_clicked));
92 _c_view.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &LuaScriptManager::callback_selection_changed));
94 vbox = manage (new VBox());
95 vbox->pack_start (_c_view, false, false);
96 vbox->pack_end (*edit_box, false, false);
99 pages.pages ().push_back (Notebook_Helpers::TabElem (*vbox, "Action Hooks"));
108 action_selection_changed ();
109 callback_selection_changed ();
113 LuaScriptManager::on_delete_event (GdkEventAny*)
119 LuaScriptManager::session_going_away ()
121 ArdourWindow::session_going_away ();
126 LuaScriptManager::setup_actions ()
128 LuaInstance *li = LuaInstance::instance();
129 for (int i = 0; i < 9; ++i) {
131 TreeModel::Row r = *_a_store->append ();
133 r[_a_model.action] = string_compose (_("Action %1"), i + 1);
134 if (li->lua_action_name (i, name)) {
135 r[_a_model.name] = name;
136 r[_a_model.enabled] = true;
138 r[_a_model.name] = _("Unset");
139 r[_a_model.enabled] = false;
145 LuaScriptManager::action_selection_changed ()
147 TreeModel::Row row = *(_a_view.get_selection()->get_selected());
149 _a_set_button.set_sensitive (true);
152 _a_set_button.set_sensitive (false);
155 if (row && row[_a_model.enabled]) {
156 _a_del_button.set_sensitive (true);
157 _a_edit_button.set_sensitive (false); // TODO
158 _a_call_button.set_sensitive (true);
160 _a_del_button.set_sensitive (false);
161 _a_edit_button.set_sensitive (false);
162 _a_call_button.set_sensitive (false);
167 LuaScriptManager::set_action_btn_clicked ()
169 TreeModel::Row row = *(_a_view.get_selection()->get_selected());
171 LuaInstance *li = LuaInstance::instance();
172 li->interactive_add (LuaScriptInfo::EditorAction, row[_a_model.id]);
176 LuaScriptManager::del_action_btn_clicked ()
178 TreeModel::Row row = *(_a_view.get_selection()->get_selected());
180 LuaInstance *li = LuaInstance::instance();
181 if (!li->remove_lua_action (row[_a_model.id])) {
187 LuaScriptManager::call_action_btn_clicked ()
189 TreeModel::Row row = *(_a_view.get_selection()->get_selected());
190 assert (row && row[_a_model.enabled]);
191 LuaInstance *li = LuaInstance::instance();
192 li->call_action (row[_a_model.id]);
196 LuaScriptManager::edit_action_btn_clicked ()
198 TreeModel::Row row = *(_a_view.get_selection()->get_selected());
200 int id = row[_a_model.id];
201 LuaInstance *li = LuaInstance::instance();
202 std::string name, script;
203 LuaScriptParamList args;
204 if (!li->lua_action (id, name, script, args)) {
208 // TODO text-editor window, update script directly
210 if (!LuaScripting::try_compile (script, args)) {
211 // compilation failed, keep editing
215 if (li->set_lua_action (id, name, script, args)) {
218 // load failed, keep editing..
220 action_selection_changed ();
224 LuaScriptManager::set_action_script_name (int i, const std::string& name)
226 typedef Gtk::TreeModel::Children type_children;
227 type_children children = _a_store->children();
228 for(type_children::iterator iter = children.begin(); iter != children.end(); ++iter) {
229 Gtk::TreeModel::Row row = *iter;
230 if (row[_a_model.id] == i) {
232 row[_a_model.enabled] = false;
233 row[_a_model.name] = _("Unset");
235 row[_a_model.enabled] = true;
236 row[_a_model.name] = name;
241 action_selection_changed ();
246 LuaScriptManager::setup_callbacks ()
248 LuaInstance *li = LuaInstance::instance();
249 std::vector<PBD::ID> ids = li->lua_slots();
250 for (std::vector<PBD::ID>::const_iterator i = ids.begin(); i != ids.end(); ++i) {
254 LuaScriptParamList lsp;
255 if (li->lua_slot (*i, name, script, ah, lsp)) {
256 set_callback_script_name (*i, name, ah);
262 LuaScriptManager::callback_selection_changed ()
264 TreeModel::Row row = *(_c_view.get_selection()->get_selected());
266 _c_del_button.set_sensitive (true);
268 _c_del_button.set_sensitive (false);
273 LuaScriptManager::add_callback_btn_clicked ()
275 LuaInstance *li = LuaInstance::instance();
276 li->interactive_add (LuaScriptInfo::EditorHook, -1);
280 LuaScriptManager::del_callback_btn_clicked ()
282 TreeModel::Row row = *(_c_view.get_selection()->get_selected());
284 LuaInstance *li = LuaInstance::instance();
285 if (!li->unregister_lua_slot (row[_c_model.id])) {
291 LuaScriptManager::set_callback_script_name (PBD::ID id, const std::string& name, const ActionHook& ah)
294 typedef Gtk::TreeModel::Children type_children;
295 type_children children = _c_store->children();
296 for(type_children::iterator iter = children.begin(); iter != children.end(); ++iter) {
297 Gtk::TreeModel::Row row = *iter;
298 PBD::ID i = row[_c_model.id];
300 _c_store->erase (iter);
305 TreeModel::Row r = *_c_store->append ();
307 r[_c_model.name] = name;
309 for (uint32_t i = 0; i < LuaSignal::LAST_SIGNAL; ++i) {
311 if (!sig.empty()) sig += ", ";
312 sig += enum2str (LuaSignal::LuaSignal (i));
315 r[_c_model.signals] = sig;
317 callback_selection_changed ();