major design changes: use glib event loop for MIDI thread/UI; rework design of BaseUI...
[ardour.git] / gtk2_ardour / ardour_ui.cc
index 16a96f1e4500ac174245486c9125bbda5f0f9f8e..a4675f4a212b92384e42a211b8bfaf5f4ecf21ce 100644 (file)
 #include "pbd/memento_command.h"
 #include "pbd/file_utils.h"
 
-#include <gtkmm2ext/gtk_ui.h>
-#include <gtkmm2ext/utils.h>
-#include <gtkmm2ext/click_box.h>
-#include <gtkmm2ext/fastmeter.h>
-#include <gtkmm2ext/stop_signal.h>
-#include <gtkmm2ext/popup.h>
-#include <gtkmm2ext/window_title.h>
+#include "gtkmm2ext/gtk_ui.h"
+#include "gtkmm2ext/utils.h"
+#include "gtkmm2ext/click_box.h"
+#include "gtkmm2ext/fastmeter.h"
+#include "gtkmm2ext/stop_signal.h"
+#include "gtkmm2ext/popup.h"
+#include "gtkmm2ext/window_title.h"
 
 #include "midi++/manager.h"
 
@@ -95,6 +95,7 @@ typedef uint64_t microseconds_t;
 #include "route_time_axis.h"
 #include "startup.h"
 #include "engine_dialog.h"
+#include "processor_box.h"
 
 #include "i18n.h"
 
@@ -114,12 +115,12 @@ sigc::signal<void,nframes_t, bool, nframes_t> ARDOUR_UI::Clock;
 
 ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[])
 
-       : Gtkmm2ext::UI (X_("Ardour"), argcp, argvp),
+       : Gtkmm2ext::UI (X_("gui"), argcp, argvp),
 
-         primary_clock (X_("primary"), false, X_("TransportClockDisplay"), true, false, true),
-         secondary_clock (X_("secondary"), false, X_("SecondaryClockDisplay"), true, false, true),
-         preroll_clock (X_("preroll"), false, X_("PreRollClock"), true, true),
-         postroll_clock (X_("postroll"), false, X_("PostRollClock"), true, true),
+         primary_clock (X_("primary"), false, X_("TransportClockDisplay"), true, true, false, true),
+         secondary_clock (X_("secondary"), false, X_("SecondaryClockDisplay"), true, true, false, true),
+         preroll_clock (X_("preroll"), false, X_("PreRollClock"), true, false, true),
+         postroll_clock (X_("postroll"), false, X_("PostRollClock"), true, false, true),
 
          /* preroll stuff */
 
@@ -128,7 +129,7 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[])
 
          /* big clock */
 
-         big_clock (X_("bigclock"), false, "BigClockNonRecording", true, false, true),
+         big_clock (X_("bigclock"), false, "BigClockNonRecording", true, true, false, true),
 
          /* transport */
 
@@ -262,6 +263,8 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[])
 
                GainMeter::setup_slider_pix ();
                RouteTimeAxisView::setup_slider_pix ();
+               SendProcessorEntry::setup_slider_pix ();
+               SessionEvent::create_per_thread_pool ("GUI", 512);
 
        } catch (failed_constructor& err) {
                error << _("could not initialize Ardour.") << endmsg;
@@ -271,7 +274,12 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[])
 
        /* we like keyboards */
 
-       keyboard = new Keyboard;
+       keyboard = new ArdourKeyboard;
+
+       XMLNode* node = ARDOUR_UI::instance()->keyboard_settings();
+       if (node) {
+               keyboard->set_state (*node, Stateful::loading_state_version);
+       }
 
        reset_dpi();
 
@@ -294,11 +302,14 @@ ARDOUR_UI::run_startup (bool should_be_new)
 
        main().run();
 
-       /* we don't return here until the startup assistant is finished */
-
        _startup->hide ();
 
-       return _startup->applying ();
+       switch (_startup->response()) {
+       case RESPONSE_OK:
+               return true;
+       default:
+               return false;
+       }
 }
 
 int
@@ -338,7 +349,7 @@ ARDOUR_UI::post_engine ()
 
        MIDI::Manager::instance()->set_api_data (engine->jack());
        setup_midi ();
-
+       
        ARDOUR::init_post_engine ();
 
        ActionManager::init ();
@@ -347,7 +358,7 @@ ARDOUR_UI::post_engine ()
        if (setup_windows ()) {
                throw failed_constructor ();
        }
-
+       
        check_memory_locking();
 
        /* this is the first point at which all the keybindings are available */
@@ -398,6 +409,9 @@ ARDOUR_UI::post_engine ()
        update_cpu_load ();
        update_sample_rate (engine->frame_rate());
 
+       Config->ParameterChanged.connect (mem_fun (*this, &ARDOUR_UI::parameter_changed));
+       Config->map_parameters (mem_fun (*this, &ARDOUR_UI::parameter_changed));
+
        /* now start and maybe save state */
 
        if (do_engine_start () == 0) {
@@ -770,7 +784,15 @@ If you still wish to quit, please use the\n\n\
                        }
                }
 
-               session->set_deletion_in_progress ();
+               second_connection.disconnect ();
+               point_one_second_connection.disconnect ();
+               point_oh_five_second_connection.disconnect ();
+               point_zero_one_second_connection.disconnect();
+               
+               // session->set_deletion_in_progress ();
+               session->remove_pending_capture_state ();
+               delete session;
+               session = 0;
        }
 
        ArdourDialog::close_all_dialogs ();
@@ -1292,7 +1314,7 @@ restart JACK with more ports."));
 
 
 void
-ARDOUR_UI::session_add_audio_route (bool track, int32_t input_channels, int32_t output_channels, ARDOUR::TrackMode mode, RouteGroup* route_group, uint32_t how_many)
+ARDOUR_UI::session_add_audio_route (bool track, bool aux, int32_t input_channels, int32_t output_channels, ARDOUR::TrackMode mode, RouteGroup* route_group, uint32_t how_many)
 {
        list<boost::shared_ptr<AudioTrack> > tracks;
        RouteList routes;
@@ -1317,7 +1339,7 @@ ARDOUR_UI::session_add_audio_route (bool track, int32_t input_channels, int32_t
 
                } else {
 
-                       routes = session->new_audio_route (input_channels, output_channels, route_group, how_many);
+                       routes = session->new_audio_route (aux, input_channels, output_channels, route_group, how_many);
 
                        if (routes.size() != how_many) {
                                if (how_many == 1) {
@@ -1377,13 +1399,12 @@ ARDOUR_UI::transport_goto_start ()
        if (session) {
                session->goto_start();
 
-
                /* force displayed area in editor to start no matter
                   what "follow playhead" setting is.
                */
 
                if (editor) {
-                       editor->reset_x_origin (session->current_start_frame());
+                       editor->center_screen (session->current_start_frame ());
                }
        }
 }
@@ -1428,7 +1449,7 @@ ARDOUR_UI::transport_goto_wallclock ()
                */
 
                if (editor) {
-                       editor->reset_x_origin (frames - (editor->current_page_frames()/2));
+                       editor->center_screen (frames);
                }
        }
 }
@@ -1437,7 +1458,7 @@ void
 ARDOUR_UI::transport_goto_end ()
 {
        if (session) {
-               nframes_t frame = session->current_end_frame();
+               nframes_t const frame = session->current_end_frame();
                session->request_locate (frame);
 
                /* force displayed area in editor to start no matter
@@ -1445,7 +1466,7 @@ ARDOUR_UI::transport_goto_end ()
                */
 
                if (editor) {
-                       editor->reset_x_origin (frame);
+                       editor->center_screen (frame);
                }
        }
 }
@@ -1524,13 +1545,14 @@ ARDOUR_UI::transport_roll ()
                return;
        }
        
-       switch (Config->get_slave_source()) {
-       case None:
-       case JACK:
-               break;
-       default:
-               /* transport controlled by the master */
-               return;
+       if (session->config.get_external_sync()) {
+               switch (session->config.get_sync_source()) {
+               case JACK:
+                       break;
+               default:
+                       /* transport controlled by the master */
+                       return;
+               }
        }
 
        bool rolling = session->transport_rolling();
@@ -1561,13 +1583,14 @@ ARDOUR_UI::toggle_roll (bool with_abort, bool roll_out_of_bounded_mode)
                return;
        }
        
-       switch (Config->get_slave_source()) {
-       case None:
-       case JACK:
-               break;
-       default:
-               /* transport controlled by the master */
-               return;
+       if (session->config.get_external_sync()) {
+               switch (session->config.get_sync_source()) {
+               case JACK:
+                       break;
+               default:
+                       /* transport controlled by the master */
+                       return;
+               }
        }
 
        bool rolling = session->transport_rolling();
@@ -2225,8 +2248,8 @@ ARDOUR_UI::ask_about_loading_existing_session (const Glib::ustring& session_path
                           true);
 
 
-       msg.set_name (X_("CleanupDialog"));
-       msg.set_title (_("Cleanup Unused Sources"));
+       msg.set_name (X_("OpenExistingDialog"));
+       msg.set_title (_("Open Existing Session"));
        msg.set_wmclass (X_("existing_session"), "Ardour");
        msg.set_position (Gtk::WIN_POS_MOUSE);
        pop_back_splash ();
@@ -2972,6 +2995,7 @@ ARDOUR_UI::add_route (Gtk::Window* float_window)
        uint32_t output_chan;
        string name_template = add_route_dialog->name_template ();
        bool track = add_route_dialog->track ();
+       bool aux = !track && add_route_dialog->aux();
        RouteGroup* route_group = add_route_dialog->route_group ();
 
        AutoConnectOption oac = Config->get_output_auto_connect();
@@ -2997,7 +3021,7 @@ ARDOUR_UI::add_route (Gtk::Window* float_window)
                if (track) {
                        session_add_audio_track (input_chan, output_chan, add_route_dialog->mode(), route_group, count);
                } else {
-                       session_add_audio_bus (input_chan, output_chan, route_group, count);
+                       session_add_audio_bus (aux, input_chan, output_chan, route_group, count);
                }
        }
 }