#include "ardour_ui.h"
#include "public_editor.h"
#include "meterbridge.h"
+#include "luainstance.h"
+#include "luawindow.h"
#include "mixer_ui.h"
#include "keyboard.h"
+#include "keyeditor.h"
#include "splash.h"
+#include "rc_option_editor.h"
#include "route_params_ui.h"
+#include "time_info_box.h"
#include "opts.h"
#include "utils.h"
-#include "i18n.h"
+#include "pbd/i18n.h"
using namespace Gtk;
using namespace PBD;
}
using namespace ARDOUR;
+using namespace Gtkmm2ext;
void
ARDOUR_UI::we_have_dependents ()
{
+ /* other windows and related key-event-handling contexts have already
+ * called Bindings::get_bindings() to setup their list of keybindings.
+ * Do that here for the global bindings.
+ */
+
+ if ((global_bindings = Bindings::get_bindings (X_("Global"))) == 0) {
+ error << _("Global keybindings are missing") << endmsg;
+ }
+
install_actions ();
- load_bindings ();
-
+ /* The monitor section relies on at least 1 action defined by us. Since that
+ * action now exists, give it a chance to use it.
+ */
+ mixer->monitor_section().use_others_actions ();
+
+ /* Create "static" actions that apply to all ProcessorBoxes
+ */
ProcessorBox::register_actions ();
/* Global, editor, mixer, processor box actions are defined now. Link
them with any bindings, so that GTK does not get a chance to define
the GTK accel map entries first when we ask the GtkUIManager to
- create menus/widgets.
+ create menus/widgets.
If GTK adds the actions to its accel map before we do, we lose our
freedom to use any keys. More precisely, we can use any keys, but
importantly they don't have menus showing the bindings, so it is
less of an issue.
*/
-
+
Gtkmm2ext::Bindings::associate_all ();
-
+
editor->setup_tooltips ();
editor->UpdateAllTransportClocks.connect (sigc::mem_fun (*this, &ARDOUR_UI::update_transport_clocks));
- /* catch up on tabbable state */
+ /* catch up on tabbable state, in the right order to leave the editor
+ * selected by default
+ */
- tabbable_state_change (*editor);
- tabbable_state_change (*mixer);
tabbable_state_change (*rc_option_editor);
-
+ tabbable_state_change (*mixer);
+ tabbable_state_change (*editor);
+
/* all actions are defined */
ActionManager::load_menus (ARDOUR_COMMAND_LINE::menus_file);
- editor->track_mixer_selection ();
- mixer->track_editor_selection ();
-
/* catch up on parameters */
-
+
boost::function<void (std::string)> pc (boost::bind (&ARDOUR_UI::parameter_changed, this, _1));
Config->map_parameters (pc);
- ARDOUR_UI_UTILS::reset_dpi ();
+ UIConfiguration::instance().reset_dpi ();
}
void
BootMessage (_("Setup Mixer"));
mixer->set_session (s);
meterbridge->set_session (s);
+ luawindow->set_session (s);
/* its safe to do this now */
gint
ARDOUR_UI::exit_on_main_window_close (GdkEventAny * /*ev*/)
{
-#ifdef TOP_MENUBAR
+#ifdef __APPLE__
/* just hide the window, and return - the top menu stays up */
editor->hide ();
return TRUE;
using namespace std;
Gtk::Notebook* nb = 0;
Gtk::Window* win = 0;
- Gtkmm2ext::Tabbable* tabbable = 0;
+ ArdourWidgets::Tabbable* tabbable = 0;
if (w == GTK_WIDGET(editor->contents().gobj())) {
win->present ();
return nb->gobj();
}
-
+
return 0; /* what was that? */
}
} else {
/* no session or session not dirty, but still ask anyway */
- Gtk::MessageDialog msg (string_compose ("Quit %1?", PROGRAM_NAME),
+ Gtk::MessageDialog msg (string_compose (_("Quit %1?"), PROGRAM_NAME),
false, /* no markup */
Gtk::MESSAGE_INFO,
Gtk::BUTTONS_YES_NO,
* the window manager/desktop can think we're taking too longer to
* handle the "delete" event
*/
-
- Glib::signal_idle().connect (sigc::mem_fun (*this, &ARDOUR_UI::idle_ask_about_quit));
-
+
+ Glib::signal_idle().connect (sigc::mem_fun (*this, &ARDOUR_UI::idle_ask_about_quit));
+
return true;
}
static GtkNotebook*
tab_window_root_drop (GtkNotebook* src,
- GtkWidget* w,
- gint x,
- gint y,
- gpointer user_data)
+ GtkWidget* w,
+ gint x,
+ gint y,
+ gpointer user_data)
{
return ARDOUR_UI::instance()->tab_window_root_drop (src, w, x, y, user_data);
}
keyboard->setup_keybindings ();
- /* we don't use a widget with its own window for the tab close button,
- which makes it impossible to rely on GTK+ to generate signals for
- events occuring "in" this widget. Instead, we pre-connect a
- handler to the relevant events on the notebook and then check
- to see if the event coordinates tell us that it occured "in"
- the close button.
- */
- _tabs.signal_button_press_event().connect (sigc::mem_fun (*this, &ARDOUR_UI::tabs_button_event), false);
- _tabs.signal_button_release_event().connect (sigc::mem_fun (*this, &ARDOUR_UI::tabs_button_event), false);
+ _tabs.set_show_border(false);
+ _tabs.signal_switch_page().connect (sigc::mem_fun (*this, &ARDOUR_UI::tabs_switch));
+ _tabs.signal_page_added().connect (sigc::mem_fun (*this, &ARDOUR_UI::tabs_page_added));
+ _tabs.signal_page_removed().connect (sigc::mem_fun (*this, &ARDOUR_UI::tabs_page_removed));
rc_option_editor = new RCOptionEditor;
rc_option_editor->StateChange.connect (sigc::mem_fun (*this, &ARDOUR_UI::tabbable_state_change));
return -1;
}
- /* order of addition affects order seen in initial window display */
-
- rc_option_editor->add_to_notebook (_tabs, _("Preferences"));
- mixer->add_to_notebook (_tabs, _("Mixer"));
- editor->add_to_notebook (_tabs, _("Editor"));
+ if (create_luawindow ()) {
+ error << _("UI: cannot setup luawindow") << endmsg;
+ return -1;
+ }
+ time_info_box = new TimeInfoBox ("ToolbarTimeInfo", false);
/* all other dialogs are created conditionally */
we_have_dependents ();
-#ifdef TOP_MENUBAR
- EventBox* status_bar_event_box = manage (new EventBox);
-
- status_bar_event_box->add (status_bar_label);
- status_bar_event_box->add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK);
- status_bar_label.set_size_request (300, -1);
-
- status_bar_label.show ();
- status_bar_event_box->show ();
+ /* order of addition affects order seen in initial window display */
- status_bar_event_box->signal_button_press_event().connect (mem_fun (*this, &ARDOUR_UI::status_bar_button_press));
+ rc_option_editor->add_to_notebook (_tabs, _("Preferences"));
+ mixer->add_to_notebook (_tabs, _("Mixer"));
+ editor->add_to_notebook (_tabs, _("Editor"));
- status_bar_hpacker.pack_start (*status_bar_event_box, true, true, 6);
- status_bar_hpacker.pack_start (menu_bar_base, false, false, 2);
-#else
top_packer.pack_start (menu_bar_base, false, false);
-#endif
main_vpacker.pack_start (top_packer, false, false);
- /* now add the transport frame to the top of main window */
-
+ ArdourWidgets::ArdourDropShadow *spacer = manage (new (ArdourWidgets::ArdourDropShadow));
+ spacer->set_size_request( -1, 4 );
+ spacer->show();
+
+ /* now add the transport sample to the top of main window */
+
+ main_vpacker.pack_start ( *spacer, false, false);
main_vpacker.pack_start (transport_frame, false, false);
main_vpacker.pack_start (_tabs, true, true);
-#ifdef TOP_MENUBAR
- main_vpacker.pack_start (status_bar_hpacker, false, false);
-#endif
+ LuaInstance::instance()->ActionChanged.connect (sigc::mem_fun (*this, &ARDOUR_UI::update_action_script_btn));
+
+ for (int i = 0; i < MAX_LUA_ACTION_SCRIPTS; ++i) {
+ std::string const a = string_compose (X_("script-action-%1"), i + 1);
+ Glib::RefPtr<Action> act = ActionManager::get_action(X_("Editor"), a.c_str());
+ assert (act);
+ action_script_call_btn[i].set_text (string_compose ("%1", i+1));
+ action_script_call_btn[i].set_related_action (act);
+ action_script_call_btn[i].signal_button_press_event().connect (sigc::bind (sigc::mem_fun(*this, &ARDOUR_UI::bind_lua_action_script), i), false);
+ if (act->get_sensitive ()) {
+ action_script_call_btn[i].set_visual_state (Gtkmm2ext::VisualState (action_script_call_btn[i].visual_state() & ~Gtkmm2ext::Insensitive));
+ } else {
+ action_script_call_btn[i].set_visual_state (Gtkmm2ext::VisualState (action_script_call_btn[i].visual_state() | Gtkmm2ext::Insensitive));
+ }
+ const int row = i % 2;
+ const int col = i / 2;
+ action_script_table.attach (action_script_call_btn[i], col, col + 1, row, row + 1, EXPAND, EXPAND, 1, 0);
+ action_script_call_btn[i].set_no_show_all ();
+ }
+ action_script_table.show ();
setup_transport();
build_menu_bar ();
setup_tooltips ();
_main_window.signal_delete_event().connect (sigc::mem_fun (*this, &ARDOUR_UI::main_window_delete_event));
-
+
/* pack the main vpacker into the main window and show everything
*/
const XMLNode* mnode = main_window_settings ();
if (mnode) {
- const XMLProperty* prop;
+ XMLProperty const * prop;
gint x = -1;
gint y = -1;
gint w = -1;
if ((prop = mnode->property (X_("y"))) != 0) {
y = atoi (prop->value());
- }
+ }
if ((prop = mnode->property (X_("w"))) != 0) {
w = atoi (prop->value());
- }
-
+ }
+
if ((prop = mnode->property (X_("h"))) != 0) {
h = atoi (prop->value());
}
if (x >= 0 && y >= 0 && w >= 0 && h >= 0) {
_main_window.set_position (Gtk::WIN_POS_NONE);
}
-
+
if (x >= 0 && y >= 0) {
_main_window.move (x, y);
}
-
+
if (w > 0 && h > 0) {
_main_window.set_default_size (w, h);
}
std::string current_tab;
-
+
if ((prop = mnode->property (X_("current-tab"))) != 0) {
current_tab = prop->value();
} else {
_tabs.set_current_page (_tabs.page_num (editor->contents()));
}
}
-
- _main_window.show_all ();
+
setup_toplevel_window (_main_window, "", this);
-
- _tabs.signal_switch_page().connect (sigc::mem_fun (*this, &ARDOUR_UI::tabs_switch));
- _tabs.signal_page_removed().connect (sigc::mem_fun (*this, &ARDOUR_UI::tabs_page_removed));
- _tabs.signal_page_added().connect (sigc::mem_fun (*this, &ARDOUR_UI::tabs_page_added));
+ _main_window.show_all ();
+
+ _tabs.set_show_tabs (false);
/* It would be nice if Gtkmm had wrapped this rather than just
* deprecating the old set_window_creation_hook() method, but oh well...
return 0;
}
+
+bool
+ARDOUR_UI::bind_lua_action_script (GdkEventButton*ev, int i)
+{
+ if (ev->button != 3) {
+ return false;
+ }
+ LuaInstance *li = LuaInstance::instance();
+ if (Gtkmm2ext::Keyboard::modifier_state_equals (ev->state, Gtkmm2ext::Keyboard::TertiaryModifier)) {
+ li->remove_lua_action (i);
+ } else {
+ li->interactive_add (LuaScriptInfo::EditorAction, i);
+ }
+ return true;
+}
+
+void
+ARDOUR_UI::update_action_script_btn (int i, const std::string& n)
+{
+ if (LuaInstance::instance()->lua_action_has_icon (i)) {
+ uintptr_t ii = i;
+ action_script_call_btn[i].set_icon (&LuaInstance::render_action_icon, (void*)ii);
+ } else {
+ action_script_call_btn[i].set_icon (0, 0);
+ }
+
+ std::string const a = string_compose (X_("script-action-%1"), i + 1);
+ Glib::RefPtr<Action> act = ActionManager::get_action(X_("Editor"), a.c_str());
+ assert (act);
+ if (n.empty ()) {
+ act->set_label (string_compose (_("Unset #%1"), i + 1));
+ act->set_tooltip (_("No action bound\nRight-click to assign"));
+ act->set_sensitive (false);
+ } else {
+ act->set_label (n);
+ act->set_tooltip (string_compose (_("%1\n\nClick to run\nRight-click to re-assign\nShift+right-click to unassign"), n));
+ act->set_sensitive (true);
+ }
+ KeyEditor::UpdateBindings ();
+}