Consolidate two more engine-checks
[ardour.git] / gtk2_ardour / lua_script_manager.cc
index 1917a7e4c71757c747a2761179df2f6f47fe859a..caf2ad7065e1f9af454aa7e9f506f3bacffb105d 100644 (file)
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
+#include <gtkmm/box.h>
+#include <gtkmm/frame.h>
+#include <gtkmm/messagedialog.h>
+
+#include "gtkmm2ext/gui_thread.h"
 #include "gtkmm2ext/utils.h"
 
+#include "ardour/session.h"
+
+#include "LuaBridge/LuaBridge.h"
+
+#include "ardour_ui.h"
 #include "lua_script_manager.h"
+#include "luawindow.h"
 #include "script_selector.h"
-#include "i18n.h"
+#include "pbd/i18n.h"
 
 using namespace std;
 using namespace Gtk;
@@ -34,6 +45,8 @@ LuaScriptManager::LuaScriptManager ()
        , _a_call_button (_("Call"))
        , _c_add_button (_("New Hook"))
        , _c_del_button (_("Remove"))
+       , _s_add_button (_("Load"))
+       , _s_del_button (_("Remove"))
 {
        /* action script page */
        _a_store = ListStore::create (_a_model);
@@ -42,6 +55,11 @@ LuaScriptManager::LuaScriptManager ()
        _a_view.append_column (_("Name"), _a_model.name);
        _a_view.get_column(0)->set_resizable (true);
        _a_view.get_column(0)->set_expand (true);
+       _a_view.get_column(1)->set_resizable (true);
+       _a_view.get_column(1)->set_expand (true);
+
+       Frame* f;
+       Gtk::Label* doc;
 
        Gtk::HBox* edit_box = manage (new Gtk::HBox);
        edit_box->set_spacing(3);
@@ -60,9 +78,18 @@ LuaScriptManager::LuaScriptManager ()
        LuaInstance::instance()->ActionChanged.connect (sigc::mem_fun (*this, &LuaScriptManager::set_action_script_name));
        LuaInstance::instance()->SlotChanged.connect (sigc::mem_fun (*this, &LuaScriptManager::set_callback_script_name));
 
+       f = manage (new Frame (_("Description")));
+       doc = manage (new Label (
+                               _("Action Scripts are user initiated actions (menu, shortcuts, toolbar-button) for batch processing or customized tasks.")
+                               ));
+       doc->set_padding (5, 5);
+       doc->set_line_wrap();
+       f->add (*doc);
+
        Gtk::VBox *vbox = manage (new VBox());
        vbox->pack_start (_a_view, false, false);
        vbox->pack_end (*edit_box, false, false);
+       vbox->pack_end (*f, false, false);
        vbox->show_all ();
 
        pages.pages ().push_back (Notebook_Helpers::TabElem (*vbox, "Action Scripts"));
@@ -72,9 +99,13 @@ LuaScriptManager::LuaScriptManager ()
        _c_store = ListStore::create (_c_model);
        _c_view.set_model (_c_store);
        _c_view.append_column (_("Name"), _c_model.name);
+       _c_view.append_column (_("Signal(s)"), _c_model.signals);
        _c_view.get_column(0)->set_resizable (true);
        _c_view.get_column(0)->set_expand (true);
-       _c_view.append_column (_("Signal(s)"), _c_model.signals);
+       _c_view.get_column(1)->set_resizable (true);
+       _c_view.get_column(1)->set_expand (true);
+       Gtk::CellRendererText* r = dynamic_cast<Gtk::CellRendererText*>(_c_view.get_column_cell_renderer (1));
+       r->property_ellipsize () = Pango::ELLIPSIZE_MIDDLE;
 
        edit_box = manage (new Gtk::HBox);
        edit_box->set_spacing(3);
@@ -85,34 +116,87 @@ LuaScriptManager::LuaScriptManager ()
        _c_del_button.signal_clicked().connect (sigc::mem_fun(*this, &LuaScriptManager::del_callback_btn_clicked));
        _c_view.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &LuaScriptManager::callback_selection_changed));
 
+       f = manage (new Frame (_("Description")));
+       doc = manage (new Label (
+                               _("Lua action hooks are event-triggered callbacks for the Editor/Mixer GUI. Once a script is registered it is automatically triggered by events to perform some task.")
+                               ));
+       doc->set_padding (5, 5);
+       doc->set_line_wrap();
+       f->add (*doc);
+
        vbox = manage (new VBox());
        vbox->pack_start (_c_view, false, false);
        vbox->pack_end (*edit_box, false, false);
+       vbox->pack_end (*f, false, false);
        vbox->show_all ();
 
        pages.pages ().push_back (Notebook_Helpers::TabElem (*vbox, "Action Hooks"));
 
+       /* session script page */
+
+       _s_store = ListStore::create (_s_model);
+       _s_view.set_model (_s_store);
+       _s_view.append_column (_("Name"), _s_model.name);
+       _s_view.get_column(0)->set_resizable (true);
+       _s_view.get_column(0)->set_expand (true);
+
+       edit_box = manage (new Gtk::HBox);
+       edit_box->set_spacing(3);
+       edit_box->pack_start (_s_add_button, true, true);
+       edit_box->pack_start (_s_del_button, true, true);
+
+       _s_add_button.signal_clicked().connect (sigc::mem_fun(*this, &LuaScriptManager::add_sess_btn_clicked));
+       _s_del_button.signal_clicked().connect (sigc::mem_fun(*this, &LuaScriptManager::del_sess_btn_clicked));
+       _s_view.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &LuaScriptManager::session_script_selection_changed));
+
+       f = manage (new Frame (_("Description")));
+       doc = manage (new Label (
+                               _("Lua session scripts are loaded into processing engine and run in realtime. They are called periodically at the start of every audio cycle in the realtime process context before any processing takes place.")
+                               ));
+       doc->set_padding (5, 5);
+       doc->set_line_wrap();
+       f->add (*doc);
+
+       vbox = manage (new VBox());
+       vbox->pack_start (_s_view, false, false);
+       vbox->pack_end (*edit_box, false, false);
+       vbox->pack_end (*f, false, false);
+       vbox->show_all ();
+
+       pages.pages ().push_back (Notebook_Helpers::TabElem (*vbox, "Session Scripts"));
+
+       /* global layout */
 
        add (pages);
        pages.show();
 
        setup_actions ();
        setup_callbacks ();
+       setup_session_scripts ();
 
        action_selection_changed ();
        callback_selection_changed ();
+       session_script_selection_changed ();
 }
 
-bool
-LuaScriptManager::on_delete_event (GdkEventAny*)
+void
+LuaScriptManager::set_session (ARDOUR::Session *s)
 {
-       return false;
+       ArdourWindow::set_session (s);
+       setup_session_scripts ();
+       if (!_session) {
+               return;
+       }
+
+       _session->LuaScriptsChanged.connect (_session_script_connection,  invalidator (*this), boost::bind (&LuaScriptManager::setup_session_scripts, this), gui_context());
+       setup_session_scripts ();
 }
 
 void
 LuaScriptManager::session_going_away ()
 {
        ArdourWindow::session_going_away ();
+       _session_script_connection.disconnect ();
        hide_all();
 }
 
@@ -120,7 +204,7 @@ void
 LuaScriptManager::setup_actions ()
 {
        LuaInstance *li = LuaInstance::instance();
-       for (int i = 0; i < 9; ++i) {
+       for (int i = 0; i < MAX_LUA_ACTION_SCRIPTS; ++i) {
                std::string name;
                TreeModel::Row r = *_a_store->append ();
                r[_a_model.id] = i;
@@ -148,7 +232,7 @@ LuaScriptManager::action_selection_changed ()
 
        if (row && row[_a_model.enabled]) {
                _a_del_button.set_sensitive (true);
-               _a_edit_button.set_sensitive (false); // TODO
+               _a_edit_button.set_sensitive (true);
                _a_call_button.set_sensitive (true);
        } else {
                _a_del_button.set_sensitive (false);
@@ -198,20 +282,7 @@ LuaScriptManager::edit_action_btn_clicked ()
        if (!li->lua_action (id, name, script, args)) {
                return;
        }
-
-       // TODO text-editor window, update script directly
-
-       if (!LuaScripting::try_compile (script, args)) {
-               // compilation failed, keep editing
-               return;
-       }
-
-       if (li->set_lua_action (id, name, script, args)) {
-               // OK
-       } else {
-               // load failed,  keep editing..
-       }
-       action_selection_changed ();
+       LuaWindow::instance()->edit_script (name, script);
 }
 
 void
@@ -310,3 +381,61 @@ LuaScriptManager::set_callback_script_name (PBD::ID id, const std::string& name,
        }
        callback_selection_changed ();
 }
+
+
+void
+LuaScriptManager::setup_session_scripts ()
+{
+       _s_store->clear ();
+       if (!_session) {
+               return;
+       }
+       std::vector<std::string> reg = _session->registered_lua_functions ();
+       for (std::vector<string>::const_iterator i = reg.begin(); i != reg.end(); ++i) {
+               TreeModel::Row r = *_s_store->append ();
+               r[_s_model.name] = *i;
+       }
+       session_script_selection_changed ();
+}
+
+void
+LuaScriptManager::session_script_selection_changed ()
+{
+       if (!_session) {
+               _s_del_button.set_sensitive (false);
+               _s_add_button.set_sensitive (false);
+               return;
+       }
+       TreeModel::Row row = *(_s_view.get_selection()->get_selected());
+       if (row) {
+               _s_del_button.set_sensitive (true);
+       } else {
+               _s_del_button.set_sensitive (false);
+       }
+       _s_add_button.set_sensitive (true);
+}
+
+void
+LuaScriptManager::add_sess_btn_clicked ()
+{
+       if (!_session) {
+               return;
+       }
+       LuaInstance *li = LuaInstance::instance();
+       li->interactive_add (LuaScriptInfo::Session, -1);
+}
+
+void
+LuaScriptManager::del_sess_btn_clicked ()
+{
+       assert (_session);
+       TreeModel::Row row = *(_s_view.get_selection()->get_selected());
+       const std::string& name = row[_s_model.name];
+       try {
+               _session->unregister_lua_function (name);
+       } catch (luabridge::LuaException const& e) {
+               string msg = string_compose (_("Session script '%1' removal failed: %2"), name, e.what ());
+               MessageDialog am (msg);
+               am.run ();
+       }
+}