summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Gareus <robin@gareus.org>2016-02-23 15:42:13 +0100
committerRobin Gareus <robin@gareus.org>2016-02-23 15:42:13 +0100
commit6b940afa36104e9d9d6c46828abb1182100689e3 (patch)
treec2f0143565e1ca65170fe67065971d5c015f470b
parent28017b4751cb5b4a8806f74b269730e8d2e37e8c (diff)
Lua Script Console Window
-rw-r--r--gtk2_ardour/ardour.menus.in1
-rw-r--r--gtk2_ardour/ardour_ui.cc3
-rw-r--r--gtk2_ardour/ardour_ui.h13
-rw-r--r--gtk2_ardour/ardour_ui_dependents.cc7
-rw-r--r--gtk2_ardour/ardour_ui_dialogs.cc24
-rw-r--r--gtk2_ardour/ardour_ui_ed.cc16
-rw-r--r--gtk2_ardour/luawindow.cc224
-rw-r--r--gtk2_ardour/luawindow.h78
-rw-r--r--gtk2_ardour/wscript1
9 files changed, 366 insertions, 1 deletions
diff --git a/gtk2_ardour/ardour.menus.in b/gtk2_ardour/ardour.menus.in
index b05989fe7a..bf79009b56 100644
--- a/gtk2_ardour/ardour.menus.in
+++ b/gtk2_ardour/ardour.menus.in
@@ -528,6 +528,7 @@
<menuitem action='detach-preferences'/>
</menu>
<menuitem action='toggle-meterbridge'/>
+ <menuitem action='toggle-luawindow'/>
<separator/>
<menuitem action='toggle-inspector'/>
<menuitem action='toggle-locations'/>
diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc
index 9e48335ff7..da2323b80a 100644
--- a/gtk2_ardour/ardour_ui.cc
+++ b/gtk2_ardour/ardour_ui.cc
@@ -124,6 +124,7 @@ typedef uint64_t microseconds_t;
#include "keyboard.h"
#include "keyeditor.h"
#include "location_ui.h"
+#include "luawindow.h"
#include "main_clock.h"
#include "missing_file_dialog.h"
#include "missing_plugin_dialog.h"
@@ -263,6 +264,7 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir)
, last_key_press_time (0)
, save_as_dialog (0)
, meterbridge (0)
+ , luawindow (0)
, rc_option_editor (0)
, speaker_config_window (X_("speaker-config"), _("Speaker Configuration"))
, add_route_dialog (X_("add-routes"), _("Add Tracks/Busses"))
@@ -654,6 +656,7 @@ ARDOUR_UI::~ARDOUR_UI ()
delete secondary_clock;
delete _process_thread;
delete meterbridge;
+ delete luawindow;
delete editor;
delete mixer;
delete nsm;
diff --git a/gtk2_ardour/ardour_ui.h b/gtk2_ardour/ardour_ui.h
index 2d76d7eaad..88006a0820 100644
--- a/gtk2_ardour/ardour_ui.h
+++ b/gtk2_ardour/ardour_ui.h
@@ -126,6 +126,8 @@ class ShuttleControl;
class Splash;
class TimeInfoBox;
class Meterbridge;
+class LuaWindow;
+class LuaScriptManager;
class MidiTracer;
class NSM_Client;
class LevelMeterHBox;
@@ -208,6 +210,8 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr
void toggle_monitor_section_visibility ();
void toggle_keep_tearoffs();
+ void lua_script_manager();
+
static PublicEditor* _instance;
/** Emitted frequently with the audible frame, false, and the edit point as
@@ -256,6 +260,9 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr
void start_duplicate_routes ();
+ void add_lua_script ();
+ void remove_lua_script ();
+
void add_video (Gtk::Window* float_window);
void remove_video ();
void start_video_server_menu (Gtk::Window* float_window);
@@ -383,6 +390,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr
void tabbable_state_change (Gtkmm2ext::Tabbable&);
void toggle_meterbridge ();
+ void toggle_luawindow ();
int setup_windows ();
void setup_transport ();
@@ -645,9 +653,11 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr
int create_mixer ();
int create_editor ();
+ int create_meterbridge ();
+ int create_luawindow ();
Meterbridge *meterbridge;
- int create_meterbridge ();
+ LuaWindow *luawindow;
/* Dialogs that can be created via new<T> */
@@ -661,6 +671,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr
WM::Proxy<RouteParams_UI> route_params;
WM::Proxy<EngineControl> audio_midi_setup;
WM::Proxy<ExportVideoDialog> export_video_dialog;
+ WM::Proxy<LuaScriptManager> lua_script_window;
/* Windows/Dialogs that require a creator method */
diff --git a/gtk2_ardour/ardour_ui_dependents.cc b/gtk2_ardour/ardour_ui_dependents.cc
index 939c7d0eeb..b67b3a83bb 100644
--- a/gtk2_ardour/ardour_ui_dependents.cc
+++ b/gtk2_ardour/ardour_ui_dependents.cc
@@ -37,6 +37,7 @@
#include "ardour_ui.h"
#include "public_editor.h"
#include "meterbridge.h"
+#include "luawindow.h"
#include "mixer_ui.h"
#include "keyboard.h"
#include "splash.h"
@@ -119,6 +120,7 @@ ARDOUR_UI::connect_dependents_to_session (ARDOUR::Session *s)
BootMessage (_("Setup Mixer"));
mixer->set_session (s);
meterbridge->set_session (s);
+ luawindow->set_session (s);
/* its safe to do this now */
@@ -257,6 +259,11 @@ ARDOUR_UI::setup_windows ()
return -1;
}
+ if (create_luawindow ()) {
+ error << _("UI: cannot setup luawindow") << endmsg;
+ return -1;
+ }
+
/* order of addition affects order seen in initial window display */
rc_option_editor->add_to_notebook (_tabs, _("Preferences"));
diff --git a/gtk2_ardour/ardour_ui_dialogs.cc b/gtk2_ardour/ardour_ui_dialogs.cc
index 9618b4c5ca..25f8243ec9 100644
--- a/gtk2_ardour/ardour_ui_dialogs.cc
+++ b/gtk2_ardour/ardour_ui_dialogs.cc
@@ -49,6 +49,7 @@
#include "gui_thread.h"
#include "keyeditor.h"
#include "location_ui.h"
+#include "luawindow.h"
#include "main_clock.h"
#include "meterbridge.h"
#include "meter_patterns.h"
@@ -667,6 +668,29 @@ ARDOUR_UI::toggle_meterbridge ()
}
void
+ARDOUR_UI::toggle_luawindow ()
+{
+ assert (editor && luawindow);
+
+ bool show = false;
+ bool obscuring = false;
+
+ if (luawindow->not_visible ()) {
+ show = true;
+ }
+ // TODO check overlap
+
+ if (show) {
+ luawindow->show_window ();
+ luawindow->present ();
+ luawindow->raise ();
+ } else {
+ luawindow->hide_window (NULL);
+ }
+}
+
+
+void
ARDOUR_UI::new_midi_tracer_window ()
{
RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("NewMIDITracer"));
diff --git a/gtk2_ardour/ardour_ui_ed.cc b/gtk2_ardour/ardour_ui_ed.cc
index f091d070ca..d5e6968f89 100644
--- a/gtk2_ardour/ardour_ui_ed.cc
+++ b/gtk2_ardour/ardour_ui_ed.cc
@@ -51,6 +51,7 @@
#include "editor.h"
#include "actions.h"
#include "meterbridge.h"
+#include "luawindow.h"
#include "mixer_ui.h"
#include "startup.h"
#include "window_manager.h"
@@ -93,6 +94,20 @@ ARDOUR_UI::create_editor ()
return 0;
}
+int
+ARDOUR_UI::create_luawindow ()
+
+{
+ try {
+ luawindow = LuaWindow::instance ();
+ }
+ catch (failed_constructor& err) {
+ return -1;
+ }
+
+ return 0;
+}
+
void
ARDOUR_UI::install_actions ()
{
@@ -273,6 +288,7 @@ ARDOUR_UI::install_actions ()
global_actions.register_action (common_actions, X_("show-ui-prefs"), _("Show more UI preferences"), sigc::mem_fun (*this, &ARDOUR_UI::show_ui_prefs));
}
+ global_actions.register_action (common_actions, X_("toggle-luawindow"), S_("Window|Scripting"), sigc::mem_fun(*this, &ARDOUR_UI::toggle_luawindow));
global_actions.register_action (common_actions, X_("toggle-meterbridge"), S_("Window|Meterbridge"), sigc::mem_fun(*this, &ARDOUR_UI::toggle_meterbridge));
act = global_actions.register_action (common_actions, X_("NewMIDITracer"), _("MIDI Tracer"), sigc::mem_fun(*this, &ARDOUR_UI::new_midi_tracer_window));
diff --git a/gtk2_ardour/luawindow.cc b/gtk2_ardour/luawindow.cc
new file mode 100644
index 0000000000..5fda4f2e24
--- /dev/null
+++ b/gtk2_ardour/luawindow.cc
@@ -0,0 +1,224 @@
+/*
+ Copyright (C) 2016 Robin Gareus <robin@gareus.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifdef WAF_BUILD
+#include "gtk2ardour-config.h"
+#endif
+
+#include <gtkmm2ext/gtk_ui.h>
+#include <gtkmm2ext/utils.h>
+#include <gtkmm2ext/window_title.h>
+
+#include "ardour_ui.h"
+#include "gui_thread.h"
+#include "luainstance.h"
+#include "luawindow.h"
+#include "public_editor.h"
+#include "utils.h"
+
+#include "ardour/luabindings.h"
+#include "LuaBridge/LuaBridge.h"
+
+#include "i18n.h"
+
+using namespace ARDOUR;
+using namespace ARDOUR_UI_UTILS;
+using namespace PBD;
+using namespace Gtk;
+using namespace Glib;
+using namespace Gtkmm2ext;
+using namespace std;
+
+
+LuaWindow* LuaWindow::_instance = 0;
+
+LuaWindow*
+LuaWindow::instance ()
+{
+ if (!_instance) {
+ _instance = new LuaWindow;
+ }
+
+ return _instance;
+}
+
+LuaWindow::LuaWindow ()
+ : Window (Gtk::WINDOW_TOPLEVEL)
+ , VisibilityTracker (*((Gtk::Window*) this))
+ , _visible (false)
+{
+ set_name ("Lua");
+
+ update_title ();
+ set_wmclass (X_("ardour_mixer"), PROGRAM_NAME);
+
+ set_border_width (0);
+
+ outtext.set_editable (false);
+ outtext.set_wrap_mode (Gtk::WRAP_WORD);
+
+ signal_delete_event().connect (sigc::mem_fun (*this, &LuaWindow::hide_window));
+ signal_configure_event().connect (sigc::mem_fun (*ARDOUR_UI::instance(), &ARDOUR_UI::configure_handler));
+
+ scrollwin.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_ALWAYS);
+ scrollwin.add (outtext);
+
+ Gtk::Button *btn_clr = manage (new Button ("Clear"));
+ btn_clr->signal_clicked().connect (sigc::mem_fun(*this, &LuaWindow::clear_output));
+
+ Gtk::HBox *hbox = manage (new HBox());
+
+ hbox->pack_start (entry, true, true, 2);
+ hbox->pack_start (*btn_clr, false, false, 0);
+
+ Gtk::VBox *vbox = manage (new VBox());
+ vbox->pack_start (scrollwin, true, true, 0);
+ vbox->pack_start (*hbox, false, false, 2);
+
+ entry.signal_activate().connect (sigc::mem_fun (*this, &LuaWindow::entry_activated));
+
+ lua.Print.connect (sigc::mem_fun (*this, &LuaWindow::append_text));
+
+ vbox->show_all ();
+ add (*vbox);
+ set_size_request (640, 480); // XXX
+
+ LuaInstance::register_classes (lua.getState());
+ // TODO register some callback functions.
+
+ lua_State* L = lua.getState();
+ luabridge::push <PublicEditor *> (L, &PublicEditor::instance());
+ lua_setglobal (L, "Editor");
+ // TODO
+ // - allow to load files
+ // - allow to run files directly
+ // - history buffer
+ // - multi-line input ??
+}
+
+LuaWindow::~LuaWindow ()
+{
+}
+
+void
+LuaWindow::show_window ()
+{
+ present();
+ _visible = true;
+}
+
+bool
+LuaWindow::hide_window (GdkEventAny *ev)
+{
+ if (!_visible) return 0;
+ _visible = false;
+ return just_hide_it (ev, static_cast<Gtk::Window *>(this));
+}
+
+void LuaWindow::set_session (Session* s)
+{
+ SessionHandlePtr::set_session (s);
+ if (!_session) {
+ return;
+ }
+
+ update_title ();
+ _session->DirtyChanged.connect (_session_connections, invalidator (*this), boost::bind (&LuaWindow::update_title, this), gui_context());
+
+ // expose "Session" point directly
+ lua_State* L = lua.getState();
+ LuaBindings::set_session (L, _session);
+}
+
+void
+LuaWindow::session_going_away ()
+{
+ ENSURE_GUI_THREAD (*this, &LuaWindow::session_going_away);
+ lua.do_command ("collectgarbage();");
+ //TODO: re-init lua-engine (drop all references) ??
+
+ SessionHandlePtr::session_going_away ();
+ _session = 0;
+ update_title ();
+
+ lua_State* L = lua.getState();
+ LuaBindings::set_session (L, _session);
+}
+
+void
+LuaWindow::update_title ()
+{
+ if (_session) {
+ string n;
+
+ if (_session->snap_name() != _session->name()) {
+ n = _session->snap_name ();
+ } else {
+ n = _session->name ();
+ }
+
+ if (_session->dirty ()) {
+ n = "*" + n;
+ }
+
+ WindowTitle title (n);
+ title += S_("Window|Lua");
+ title += Glib::get_application_name ();
+ set_title (title.get_string());
+
+ } else {
+ WindowTitle title (S_("Window|Lua"));
+ title += Glib::get_application_name ();
+ set_title (title.get_string());
+ }
+}
+
+void
+LuaWindow::scroll_to_bottom ()
+{
+ Gtk::Adjustment *adj;
+ adj = scrollwin.get_vadjustment();
+ adj->set_value (MAX(0,(adj->get_upper() - adj->get_page_size())));
+}
+
+void
+LuaWindow::entry_activated ()
+{
+ std::string cmd = entry.get_text();
+ append_text ("> " + cmd);
+
+ if (0 == lua.do_command (cmd)) {
+ entry.set_text("");
+ }
+}
+
+void
+LuaWindow::append_text (std::string s)
+{
+ Glib::RefPtr<Gtk::TextBuffer> tb (outtext.get_buffer());
+ tb->insert (tb->end(), s + "\n");
+ scroll_to_bottom ();
+}
+
+void
+LuaWindow::clear_output ()
+{
+ Glib::RefPtr<Gtk::TextBuffer> tb (outtext.get_buffer());
+ tb->set_text ("");
+}
diff --git a/gtk2_ardour/luawindow.h b/gtk2_ardour/luawindow.h
new file mode 100644
index 0000000000..9a7f281f3e
--- /dev/null
+++ b/gtk2_ardour/luawindow.h
@@ -0,0 +1,78 @@
+/*
+ Copyright (C) 2016 Robin Gareus <robin@gareus.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+#ifndef __ardour_luawindow_h__
+#define __ardour_luawindow_h__
+
+#include <glibmm/thread.h>
+
+#include <gtkmm/box.h>
+#include <gtkmm/scrolledwindow.h>
+#include <gtkmm/label.h>
+#include <gtkmm/window.h>
+
+#include "ardour/ardour.h"
+#include "ardour/types.h"
+#include "ardour/session_handle.h"
+
+#include "pbd/stateful.h"
+#include "pbd/signals.h"
+
+#include "gtkmm2ext/visibility_tracker.h"
+
+#include "lua/luastate.h"
+
+class LuaWindow :
+ public Gtk::Window,
+ public PBD::ScopedConnectionList,
+ public ARDOUR::SessionHandlePtr,
+ public Gtkmm2ext::VisibilityTracker
+{
+ public:
+ static LuaWindow* instance();
+ ~LuaWindow();
+
+ void show_window ();
+ bool hide_window (GdkEventAny *ev);
+
+ void set_session (ARDOUR::Session* s);
+
+ private:
+ LuaWindow ();
+ static LuaWindow* _instance;
+
+ bool _visible;
+ Gtk::VBox global_vpacker;
+
+ void session_going_away ();
+ void update_title ();
+
+ Gtk::Entry entry;
+ Gtk::TextView outtext;
+ Gtk::ScrolledWindow scrollwin;
+
+ void append_text (std::string s);
+ void scroll_to_bottom ();
+ void clear_output ();
+
+ void entry_activated ();
+
+ LuaState lua;
+};
+
+#endif
diff --git a/gtk2_ardour/wscript b/gtk2_ardour/wscript
index 8d9a3362b4..de73078287 100644
--- a/gtk2_ardour/wscript
+++ b/gtk2_ardour/wscript
@@ -123,6 +123,7 @@ gtk2_ardour_sources = [
'level_meter.cc',
'location_ui.cc',
'luainstance.cc',
+ 'luawindow.cc',
'main.cc',
'main_clock.cc',
'marker.cc',