#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;
update_format ();
if (meter_box.get_parent()) {
- transport_tearoff_hbox.remove (meter_box);
- transport_tearoff_hbox.remove (editor_meter_peak_display);
+ transport_hbox.remove (meter_box);
+ transport_hbox.remove (editor_meter_peak_display);
}
if (editor_meter) {
}
if (meter_box.get_parent()) {
- transport_tearoff_hbox.remove (meter_box);
- transport_tearoff_hbox.remove (editor_meter_peak_display);
+ transport_hbox.remove (meter_box);
+ transport_hbox.remove (editor_meter_peak_display);
}
if (_session &&
editor_meter_peak_display.signal_button_release_event().connect (sigc::mem_fun(*this, &ARDOUR_UI::editor_meter_peak_button_release), false);
if (UIConfiguration::instance().get_show_editor_meter() && !ARDOUR::Profile->get_trx()) {
- transport_tearoff_hbox.pack_start (meter_box, false, false);
- transport_tearoff_hbox.pack_start (editor_meter_peak_display, false, false);
+ transport_hbox.pack_start (meter_box, false, false);
+ transport_hbox.pack_start (editor_meter_peak_display, false, false);
meter_box.show();
editor_meter_peak_display.show();
}
update_buffer_load ();
update_title ();
-
+
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)
{
if (!t) {
return;
}
-
+
t->make_visible ();
}
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 (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 (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 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);
+ }
+
+}
+
void
ARDOUR_UI::tabbable_state_change (Tabbable& t)
{
std::vector<std::string> insensitive_action_names;
std::vector<std::string> sensitive_action_names;
- Glib::RefPtr<Action> action;
+ std::vector<std::string> active_action_names;
+ std::vector<std::string> inactive_action_names;
+ Glib::RefPtr<Action> action;
std::string downcased_name = downcase (t.name());
+ enum ViewState {
+ Tabbed,
+ Windowed,
+ Hidden
+ };
+ ViewState vs;
- std::cerr << t.name() << " changed state\n";
-
if (t.tabbed()) {
- std::cerr << "tabbed\n";
-
insensitive_action_names.push_back (string_compose ("attach-%1", downcased_name));
- insensitive_action_names.push_back (string_compose ("show-%1", downcased_name));
+ sensitive_action_names.push_back (string_compose ("show-%1", downcased_name));
sensitive_action_names.push_back (string_compose ("detach-%1", downcased_name));
sensitive_action_names.push_back (string_compose ("hide-%1", downcased_name));
+ vs = Tabbed;
- } else if (t.window_visible()) {
+ } else if (t.tabbed_by_default ()) {
+
+ insensitive_action_names.push_back (string_compose ("attach-%1", downcased_name));
+ insensitive_action_names.push_back (string_compose ("hide-%1", downcased_name));
+ sensitive_action_names.push_back (string_compose ("show-%1", downcased_name));
+ sensitive_action_names.push_back (string_compose ("detach-%1", downcased_name));
- std::cerr << "windowed\n";
+ vs = Hidden;
+
+ } else if (t.window_visible()) {
insensitive_action_names.push_back (string_compose ("detach-%1", downcased_name));
- insensitive_action_names.push_back (string_compose ("show-%1", downcased_name));
+ sensitive_action_names.push_back (string_compose ("show-%1", downcased_name));
sensitive_action_names.push_back (string_compose ("attach-%1", downcased_name));
sensitive_action_names.push_back (string_compose ("hide-%1", downcased_name));
+ active_action_names.push_back (string_compose ("show-%1", downcased_name));
+ inactive_action_names.push_back (string_compose ("hide-%1", downcased_name));
+
+ vs = Windowed;
+
} else {
- std::cerr << "invisible\n";
-
/* not currently visible. allow user to retab it or just make
* it visible.
*/
-
+
insensitive_action_names.push_back (string_compose ("detach-%1", downcased_name));
insensitive_action_names.push_back (string_compose ("hide-%1", downcased_name));
sensitive_action_names.push_back (string_compose ("show-%1", downcased_name));
sensitive_action_names.push_back (string_compose ("attach-%1", downcased_name));
- }
+ active_action_names.push_back (string_compose ("hide-%1", downcased_name));
+ inactive_action_names.push_back (string_compose ("show-%1", downcased_name));
+
+ vs = Hidden;
+ }
for (std::vector<std::string>::iterator s = insensitive_action_names.begin(); s != insensitive_action_names.end(); ++s) {
action = ActionManager::get_action (X_("Common"), (*s).c_str());
action->set_sensitive (true);
}
}
+
+ ArdourButton* vis_button = 0;
+ std::vector<ArdourButton*> other_vis_buttons;
+
+ if (&t == editor) {
+ vis_button = &editor_visibility_button;
+ other_vis_buttons.push_back (&mixer_visibility_button);
+ other_vis_buttons.push_back (&prefs_visibility_button);
+ } else if (&t == mixer) {
+ vis_button = &mixer_visibility_button;
+ other_vis_buttons.push_back (&editor_visibility_button);
+ other_vis_buttons.push_back (&prefs_visibility_button);
+ } 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);
+ }
+
+ if (!vis_button) {
+ return;
+ }
+
+ switch (vs) {
+ case Tabbed:
+ vis_button->set_active_state (Gtkmm2ext::ImplicitActive);
+ break;
+ case Windowed:
+ vis_button->set_active_state (Gtkmm2ext::ExplicitActive);
+ break;
+ case Hidden:
+ 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*
+ARDOUR_UI::create_key_editor ()
+{
+ KeyEditor* kedit = new KeyEditor;
+
+ for (std::list<Bindings*>::iterator b = Bindings::bindings.begin(); b != Bindings::bindings.end(); ++b) {
+ kedit->add_tab ((*b)->name(), **b);
+ }
+
+ return kedit;
+}
+
BundleManager*
ARDOUR_UI::create_bundle_manager ()
{