#include "ardour/control_protocol_manager.h"
#include "ardour/profile.h"
#include "ardour/session.h"
+
#include "control_protocol/control_protocol.h"
+#include "gtkmm2ext/keyboard.h"
+#include "gtkmm2ext/utils.h"
+
#include "actions.h"
#include "add_route_dialog.h"
#include "add_video_dialog.h"
#include "gui_thread.h"
#include "keyeditor.h"
#include "location_ui.h"
+#include "lua_script_manager.h"
+#include "luawindow.h"
#include "main_clock.h"
#include "meterbridge.h"
#include "meter_patterns.h"
+#include "monitor_section.h"
#include "midi_tracer.h"
#include "mixer_ui.h"
#include "public_editor.h"
+#include "processor_box.h"
#include "rc_option_editor.h"
#include "route_params_ui.h"
#include "shuttle_control.h"
#include "time_info_box.h"
#include "timers.h"
-#include <gtkmm2ext/keyboard.h>
-
-#include "i18n.h"
+#include "pbd/i18n.h"
using namespace ARDOUR;
using namespace PBD;
return 0;
}
+void
+ARDOUR_UI::toggle_editor_and_mixer ()
+{
+ if (editor->tabbed() && mixer->tabbed()) {
+ /* both in the same window */
+ if (_tabs.get_current_page() == _tabs.page_num (editor->contents())) {
+ _tabs.set_current_page (_tabs.page_num (mixer->contents()));
+ } else if (_tabs.get_current_page() == _tabs.page_num (mixer->contents())) {
+ _tabs.set_current_page (_tabs.page_num (editor->contents()));
+ } else {
+ /* go to mixer */
+ _tabs.set_current_page (_tabs.page_num (mixer->contents()));
+ }
+ return;
+ }
+
+
+ if (editor->tabbed() && !mixer->tabbed()) {
+ /* editor is tabbed, mixer is not */
+
+ Gtk::Window* mwin = mixer->current_toplevel ();
+
+ if (!mwin) {
+ /* mixer's own window doesn't exist */
+ mixer->make_visible ();
+ } else if (!mwin->is_mapped ()) {
+ /* mixer's own window exists but isn't mapped */
+ mixer->make_visible ();
+ } else {
+ /* mixer window is mapped, editor is visible as tab */
+ Gtk::Widget* f = mwin->get_focus();
+ if (f && f->has_focus()) {
+ /* mixer has focus, switch to editor */
+ editor->make_visible ();
+ } else {
+ mixer->make_visible ();
+ }
+ }
+ return;
+ }
+
+ if (!editor->tabbed() && mixer->tabbed()) {
+ /* mixer is tabbed, editor is not */
+
+ Gtk::Window* ewin = editor->current_toplevel ();
+
+ if (!ewin) {
+ /* mixer's own window doesn't exist */
+ editor->make_visible ();
+ } else if (!ewin->is_mapped ()) {
+ /* editor's own window exists but isn't mapped */
+ editor->make_visible ();
+ } else {
+ /* editor window is mapped, mixer is visible as tab */
+ Gtk::Widget* f = ewin->get_focus();
+ if (f && f->has_focus()) {
+ /* editor has focus, switch to mixer */
+ mixer->make_visible ();
+ } else {
+ editor->make_visible ();
+ }
+ }
+ return;
+ }
+}
+
+void
+ARDOUR_UI::step_up_through_tabs ()
+{
+ std::vector<Tabbable*> candidates;
+
+ /* this list must match the order of visibility buttons */
+
+ if (!editor->window_visible()) {
+ candidates.push_back (editor);
+ }
+
+ if (!mixer->window_visible()) {
+ candidates.push_back (mixer);
+ }
+
+ if (!rc_option_editor->window_visible()) {
+ candidates.push_back (rc_option_editor);
+ }
+
+ if (candidates.size() < 2) {
+ /* nothing to be done with zero or one visible in tabs */
+ return;
+ }
+
+ std::vector<Tabbable*>::iterator prev = candidates.end();
+ std::vector<Tabbable*>::iterator i;
+ Gtk::Widget* w = _tabs.get_nth_page (_tabs.get_current_page ());
+
+ for (i = candidates.begin(); i != candidates.end(); ++i) {
+ if (w == &(*i)->contents()) {
+ if (prev != candidates.end()) {
+ _tabs.set_current_page (_tabs.page_num ((*prev)->contents()));
+ } else {
+ _tabs.set_current_page (_tabs.page_num (candidates.back()->contents()));
+ }
+ return;
+ }
+ prev = i;
+ }
+}
+
+void
+ARDOUR_UI::step_down_through_tabs ()
+{
+ std::vector<Tabbable*> candidates;
+
+ /* this list must match the order of visibility buttons */
+
+ if (!editor->window_visible()) {
+ candidates.push_back (editor);
+ }
+
+ if (!mixer->window_visible()) {
+ candidates.push_back (mixer);
+ }
+
+ if (!rc_option_editor->window_visible()) {
+ candidates.push_back (rc_option_editor);
+ }
+
+ if (candidates.size() < 2) {
+ /* nothing to be done with zero or one visible in tabs */
+ return;
+ }
+
+ std::vector<Tabbable*>::reverse_iterator next = candidates.rend();
+ std::vector<Tabbable*>::reverse_iterator i;
+ Gtk::Widget* w = _tabs.get_nth_page (_tabs.get_current_page ());
+
+ for (i = candidates.rbegin(); i != candidates.rend(); ++i) {
+ if (w == &(*i)->contents()) {
+ if (next != candidates.rend()) {
+ _tabs.set_current_page (_tabs.page_num ((*next)->contents()));
+ } else {
+ _tabs.set_current_page (_tabs.page_num (candidates.front()->contents()));
+ }
+ break;
+ }
+ next = i;
+ }
+}
+
+void
+ARDOUR_UI::key_change_tabbable_visibility (Tabbable* t)
+{
+ if (!t) {
+ return;
+ }
+
+ if (t->tabbed()) {
+ _tabs.set_current_page (_tabs.page_num (t->contents()));
+ } else if (!t->fully_visible()) {
+ t->make_visible ();
+ } else {
+ _main_window.present ();
+ }
+}
+
+void
+ARDOUR_UI::button_change_tabbable_visibility (Tabbable* t)
+{
+ /* For many/most users, clicking a button in the main window will make it
+ the main/front/key window, which will change any stacking relationship they
+ were trying to modify by clicking on the button in the first
+ place. This button-aware method knows that click on
+ a button designed to show/hide a Tabbable that has its own window
+ will have made that window be obscured (as the main window comes to
+ the front). We therefore *hide* the Tabbable's window if it is even
+ partially visible, believing that this is likely because the
+ Tabbable window used to be front, the user clicked to change that,
+ and before we even get here, the main window has become front.
+ */
+
+ if (!t) {
+ return;
+ }
+
+ if (t->tabbed()) {
+ _tabs.set_current_page (_tabs.page_num (t->contents()));
+ } else if (t->visible()) {
+ t->hide();
+ } else {
+ t->make_visible ();
+ }
+}
+
void
ARDOUR_UI::show_tabbable (Tabbable* t)
{
t->detach ();
}
+void
+ARDOUR_UI::tabs_page_added (Widget*,guint)
+{
+ if (_tabs.get_n_pages() > 1) {
+
+ std::vector<TargetEntry> drag_target_entries;
+ drag_target_entries.push_back (TargetEntry ("tabbable"));
+
+ editor_visibility_button.drag_source_set (drag_target_entries);
+ mixer_visibility_button.drag_source_set (drag_target_entries);
+ prefs_visibility_button.drag_source_set (drag_target_entries);
+
+ editor_visibility_button.drag_source_set_icon (Gtkmm2ext::pixbuf_from_string (editor->name(),
+ Pango::FontDescription ("Sans 24"),
+ 0, 0,
+ Gdk::Color ("red")));
+ mixer_visibility_button.drag_source_set_icon (Gtkmm2ext::pixbuf_from_string (mixer->name(),
+ Pango::FontDescription ("Sans 24"),
+ 0, 0,
+ Gdk::Color ("red")));
+ prefs_visibility_button.drag_source_set_icon (Gtkmm2ext::pixbuf_from_string (rc_option_editor->name(),
+ Pango::FontDescription ("Sans 24"),
+ 0, 0,
+ Gdk::Color ("red")));
+ }
+}
+
+void
+ARDOUR_UI::tabs_page_removed (Widget*, guint)
+{
+ if (_tabs.get_n_pages() < 2) {
+ editor_visibility_button.drag_source_unset ();
+ mixer_visibility_button.drag_source_unset ();
+ prefs_visibility_button.drag_source_unset ();
+ }
+}
+
void
ARDOUR_UI::tabs_switch (GtkNotebookPage*, guint page)
{
- if (page == _tabs.page_num (editor->contents())) {
+ if (editor && (page == (guint) _tabs.page_num (editor->contents()))) {
editor_visibility_button.set_active_state (Gtkmm2ext::ImplicitActive);
+
if (mixer && (mixer->tabbed() || mixer->tabbed_by_default())) {
mixer_visibility_button.set_active_state (Gtkmm2ext::Off);
}
+
if (rc_option_editor && (rc_option_editor->tabbed() || rc_option_editor->tabbed_by_default())) {
prefs_visibility_button.set_active_state (Gtkmm2ext::Off);
}
- } else if (page == _tabs.page_num (mixer->contents())) {
+ } else if (mixer && (page == (guint) _tabs.page_num (mixer->contents()))) {
+
if (editor && (editor->tabbed() || editor->tabbed_by_default())) {
editor_visibility_button.set_active_state (Gtkmm2ext::Off);
}
+
mixer_visibility_button.set_active_state (Gtkmm2ext::ImplicitActive);
if (rc_option_editor && (rc_option_editor->tabbed() || rc_option_editor->tabbed_by_default())) {
prefs_visibility_button.set_active_state (Gtkmm2ext::Off);
}
- } else {
+
+ } else if (page == (guint) _tabs.page_num (rc_option_editor->contents())) {
+
if (editor && (editor->tabbed() || editor->tabbed_by_default())) {
editor_visibility_button.set_active_state (Gtkmm2ext::Off);
}
+
if (mixer && (mixer->tabbed() || mixer->tabbed_by_default())) {
mixer_visibility_button.set_active_state (Gtkmm2ext::Off);
}
+
prefs_visibility_button.set_active_state (Gtkmm2ext::ImplicitActive);
}
vis_button = &mixer_visibility_button;
other_vis_buttons.push_back (&editor_visibility_button);
other_vis_buttons.push_back (&prefs_visibility_button);
- } else {
+ } else if (&t == rc_option_editor) {
vis_button = &prefs_visibility_button;
other_vis_buttons.push_back (&editor_visibility_button);
other_vis_buttons.push_back (&mixer_visibility_button);
vis_button->set_active_state (Gtkmm2ext::Off);
break;
}
+
+ for (std::vector<ArdourButton*>::iterator b = other_vis_buttons.begin(); b != other_vis_buttons.end(); ++b) {
+ (*b)->set_active_state (Gtkmm2ext::Off);
+ }
}
void
obscuring = true;
}
- if (obscuring && (editor->own_window()->property_has_toplevel_focus() || (mixer->own_window() && mixer->own_window()->property_has_toplevel_focus()))) {
+ if (obscuring && ((editor->own_window() && editor->own_window()->property_has_toplevel_focus()) ||
+ (mixer->own_window() && mixer->own_window()->property_has_toplevel_focus()))) {
show = true;
}
}
}
+void
+ARDOUR_UI::toggle_luawindow ()
+{
+ assert (editor && luawindow);
+
+ bool show = 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 ()
{
{
KeyEditor* kedit = new KeyEditor;
- if (global_bindings) {
- kedit->add_tab (_("Global"), *global_bindings);
- }
-
- if (editor->bindings) {
- kedit->add_tab (_("Editing"), *editor->bindings);
- }
-
- if (mixer->bindings) {
- kedit->add_tab (_("Mixing"), *mixer->bindings);
+ for (std::list<Bindings*>::iterator b = Bindings::bindings.begin(); b != Bindings::bindings.end(); ++b) {
+ kedit->add_tab ((*b)->name(), **b);
}
return kedit;