use home-grown solution for path_expand(), rather than wordexp() which is broken...
[ardour.git] / gtk2_ardour / ardour_ui2.cc
index 70962befd60b2628edf5bbce41d7c960f85741d7..e7cac302f7051888e0ae1dc03db91a30575d8936 100644 (file)
@@ -132,12 +132,11 @@ ARDOUR_UI::setup_tooltips ()
        set_tip (goto_start_button, _("Go to start of session"));
        set_tip (goto_end_button, _("Go to end of session"));
        set_tip (auto_loop_button, _("Play loop range"));
+       set_tip (midi_panic_button, _("MIDI Panic\nSend note off and reset controller messages on all MIDI channels"));
 
        set_tip (auto_return_button, _("Return to last playback start when stopped"));
        set_tip (auto_play_button, _("Start playback after any locate"));
        set_tip (auto_input_button, _("Be sensible about input monitoring"));
-       set_tip (punch_in_button, _("Start recording at auto-punch start"));
-       set_tip (punch_out_button, _("Stop recording at auto-punch end"));
        set_tip (click_button, _("Enable/Disable audio click"));
        set_tip (time_master_button, string_compose (_("Does %1 control the time?"), PROGRAM_NAME));
        set_tip (solo_alert_button, _("When active, something is soloed.\nClick to de-solo everything"));
@@ -212,6 +211,11 @@ ARDOUR_UI::tearoff_settings (const char* name) const
 void
 ARDOUR_UI::setup_transport ()
 {
+       RefPtr<Action> act;
+
+       transport_tearoff_hbox.set_border_width (3);
+       transport_tearoff_hbox.set_spacing (3);
+
        transport_tearoff = manage (new TearOff (transport_tearoff_hbox));
        transport_tearoff->set_name ("TransportBase");
        transport_tearoff->tearoff_window().signal_key_press_event().connect (sigc::bind (sigc::ptr_fun (relay_key_press), &transport_tearoff->tearoff_window()), false);
@@ -238,82 +242,63 @@ ARDOUR_UI::setup_transport ()
        transport_tearoff->Visible.connect (sigc::bind (sigc::mem_fun(*this, &ARDOUR_UI::reattach_tearoff), static_cast<Box*> (&top_packer),
                                                  static_cast<Widget*> (&transport_frame), 1));
 
-       goto_start_button.set_name ("TransportButton");
-       goto_end_button.set_name ("TransportButton");
-       roll_button.set_name ("TransportButton");
-       stop_button.set_name ("TransportButton");
-       play_selection_button.set_name ("TransportButton");
-       rec_button.set_name ("TransportRecButton");
-       auto_loop_button.set_name ("TransportButton");
-       join_play_range_button.set_name ("TransportButton");
-
-       auto_return_button.set_name ("TransportButton");
-       auto_play_button.set_name ("TransportButton");
-       auto_input_button.set_name ("TransportButton");
-       punch_in_button.set_name ("TransportButton");
-       punch_out_button.set_name ("TransportButton");
-       click_button.set_name ("TransportButton");
-       time_master_button.set_name ("TransportButton");
-       sync_button.set_name ("TransportSyncButton");
-
-       stop_button.set_size_request(29, -1);
-       roll_button.set_size_request(29, -1);
-       auto_loop_button.set_size_request(29, -1);
-       play_selection_button.set_size_request(29, -1);
-       goto_start_button.set_size_request(29, -1);
-       goto_end_button.set_size_request(29, -1);
-       rec_button.set_size_request(29, -1);
-
-       Widget* w;
-
-       stop_button.set_visual_state (1);
-
-       w = manage (new Image (get_icon (X_("transport_start"))));
-       w->show();
-       goto_start_button.add (*w);
-       w = manage (new Image (get_icon (X_("transport_end"))));
-       w->show();
-       goto_end_button.add (*w);
-       w = manage (new Image (get_icon (X_("transport_play"))));
-       w->show();
-       roll_button.add (*w);
-       w = manage (new Image (get_icon (X_("transport_stop"))));
-       w->show();
-       stop_button.add (*w);
-       w = manage (new Image (get_icon (X_("transport_range"))));
-       w->show();
-       play_selection_button.add (*w);
-       w = manage (new Image (get_icon (X_("transport_record"))));
-       w->show();
-       rec_button.add (*w);
-       w = manage (new Image (get_icon (X_("transport_loop"))));
-       w->show();
-       auto_loop_button.add (*w);
-       w = manage (new Image (get_icon (X_("tool_object_range"))));
-       w->show ();
-       join_play_range_button.add (*w);
+       auto_return_button.set_text(_("Auto Return"));
+       auto_play_button.set_text(_("Auto Play"));
+       auto_input_button.set_text (_("Auto Input"));
 
-       RefPtr<Action> act;
+       click_button.set_image (get_icon (X_("metronome")));
+       act = ActionManager::get_action ("Transport", "ToggleClick");
+       click_button.set_related_action (act);
+       click_button.signal_button_press_event().connect (sigc::mem_fun (*this, &ARDOUR_UI::click_button_clicked), false);
+
+       auto_return_button.set_name ("transport option button");
+       auto_play_button.set_name ("transport option button");
+       auto_input_button.set_name ("transport option button");
+       time_master_button.set_name ("transport option button");
+
+       /* these have to provide a clear indication of active state */
+
+       click_button.set_name ("transport active option button");
+       sync_button.set_name ("transport active option button");
+
+       time_master_button.set_text (_("time master"));
+
+       stop_button.set_active_state (Active);
 
+       goto_start_button.set_image (get_icon (X_("transport_start")));
+       goto_end_button.set_image (get_icon (X_("transport_end")));
+       roll_button.set_image (get_icon (X_("transport_play")));
+       stop_button.set_image (get_icon (X_("transport_stop")));
+       play_selection_button.set_image (get_icon (X_("transport_range")));
+       rec_button.set_image (get_icon (X_("transport_record")));
+       auto_loop_button.set_image (get_icon (X_("transport_loop")));
+       join_play_range_button.set_image (get_icon (X_("tool_object_range")));
+
+       midi_panic_button.set_image (get_icon (X_("midi_panic")));
+       /* the icon for this has an odd aspect ratio, so fatten up the button */
+       midi_panic_button.set_size_request (25, -1);
+       
        act = ActionManager::get_action (X_("Transport"), X_("Stop"));
-       act->connect_proxy (stop_button);
+       stop_button.set_related_action (act);
        act = ActionManager::get_action (X_("Transport"), X_("Roll"));
-       act->connect_proxy (roll_button);
+       roll_button.set_related_action (act);
        act = ActionManager::get_action (X_("Transport"), X_("Record"));
-       act->connect_proxy (rec_button);
+       rec_button.set_related_action (act);
        act = ActionManager::get_action (X_("Transport"), X_("GotoStart"));
-       act->connect_proxy (goto_start_button);
+       goto_start_button.set_related_action (act);
        act = ActionManager::get_action (X_("Transport"), X_("GotoEnd"));
-       act->connect_proxy (goto_end_button);
+       goto_end_button.set_related_action (act);
        act = ActionManager::get_action (X_("Transport"), X_("Loop"));
-       act->connect_proxy (auto_loop_button);
+       auto_loop_button.set_related_action (act);
        act = ActionManager::get_action (X_("Transport"), X_("PlaySelection"));
-       act->connect_proxy (play_selection_button);
+       play_selection_button.set_related_action (act);
+       act = ActionManager::get_action (X_("MIDI"), X_("panic"));
+       midi_panic_button.set_related_action (act);
+
        act = ActionManager::get_action (X_("Transport"), X_("ToggleTimeMaster"));
-       act->connect_proxy (time_master_button);
+       time_master_button.set_related_action (act);
        act = ActionManager::get_action (X_("Transport"), X_("ToggleExternalSync"));
-       act->connect_proxy (sync_button);
-
+       sync_button.set_related_action (act);
 
        /* clocks, etc. */
 
@@ -324,85 +309,81 @@ ARDOUR_UI::setup_transport ()
        secondary_clock->ValueChanged.connect (sigc::mem_fun(*this, &ARDOUR_UI::secondary_clock_value_changed));
        big_clock->ValueChanged.connect (sigc::mem_fun(*this, &ARDOUR_UI::big_clock_value_changed));
 
-       ActionManager::get_action ("Transport", "ToggleAutoReturn")->connect_proxy (auto_return_button);
-       ActionManager::get_action ("Transport", "ToggleAutoPlay")->connect_proxy (auto_play_button);
-       ActionManager::get_action ("Transport", "ToggleAutoInput")->connect_proxy (auto_input_button);
-       ActionManager::get_action ("Transport", "ToggleClick")->connect_proxy (click_button);
-       ActionManager::get_action ("Transport", "TogglePunchIn")->connect_proxy (punch_in_button);
-       ActionManager::get_action ("Transport", "TogglePunchOut")->connect_proxy (punch_out_button);
-
-       click_button.signal_button_press_event().connect (sigc::mem_fun (*this, &ARDOUR_UI::click_button_clicked), false);
-
-       preroll_button.set_name ("TransportButton");
-       postroll_button.set_name ("TransportButton");
-
-       preroll_clock->set_mode (AudioClock::MinSec);
-       preroll_clock->set_name ("TransportClockDisplay");
-       postroll_clock->set_mode (AudioClock::MinSec);
-       postroll_clock->set_name ("TransportClockDisplay");
+       act = ActionManager::get_action ("Transport", "ToggleAutoReturn");
+       auto_return_button.set_related_action (act);
+       act = ActionManager::get_action ("Transport", "ToggleAutoPlay");
+       auto_play_button.set_related_action (act);
+       act = ActionManager::get_action ("Transport", "ToggleAutoInput");
+       auto_input_button.set_related_action (act);
 
        /* alerts */
 
        /* CANNOT sigc::bind these to clicked or toggled, must use pressed or released */
 
-       solo_alert_button.set_name ("TransportSoloAlert");
+       solo_alert_button.set_name ("rude solo");
        solo_alert_button.signal_button_press_event().connect (sigc::mem_fun(*this,&ARDOUR_UI::solo_alert_press), false);
-       auditioning_alert_button.set_name ("TransportAuditioningAlert");
+       auditioning_alert_button.set_name ("rude audition");
        auditioning_alert_button.signal_button_press_event().connect (sigc::mem_fun(*this,&ARDOUR_UI::audition_alert_press), false);
 
-       alert_box.pack_start (solo_alert_button, false, false);
-       alert_box.pack_start (auditioning_alert_button, false, false);
+       alert_box.pack_start (solo_alert_button, true, false);
+       alert_box.pack_start (auditioning_alert_button, true, false);
 
-       HBox* transport_hbox = manage (new HBox);
+       HBox* tbox = manage (new HBox);
+       tbox->set_spacing (2);
 
-       transport_tearoff_hbox.set_border_width (3);
-
-       transport_hbox->pack_start (goto_start_button, false, false);
-       transport_hbox->pack_start (goto_end_button, false, false);
+       tbox->pack_start (midi_panic_button, false, false);
+       tbox->pack_start (goto_start_button, false, false);
+       tbox->pack_start (goto_end_button, false, false);
 
        /* translators: Egternal is "External" with a descender character */
        set_size_request_to_display_given_text (sync_button, X_("Egternal"), 4, 10);
 
-       // transport_tearoff_hbox.pack_start (*svbox, false, false, 3);
+       Glib::RefPtr<SizeGroup> transport_button_size_group1 = SizeGroup::create (SIZE_GROUP_HORIZONTAL);
+       transport_button_size_group1->add_widget (goto_start_button);
+       transport_button_size_group1->add_widget (goto_end_button);
+       transport_button_size_group1->add_widget (auto_loop_button);
+       transport_button_size_group1->add_widget (rec_button);
 
        if (Profile->get_sae()) {
-               transport_hbox->pack_start (auto_loop_button);
-               transport_hbox->pack_start (roll_button);
+               tbox->pack_start (auto_loop_button);
+               tbox->pack_start (roll_button);
+               transport_button_size_group1->add_widget (play_selection_button);
+               transport_button_size_group1->add_widget (roll_button);
+
        } else {
-               transport_hbox->pack_start (auto_loop_button, false, false);
+
+               tbox->pack_start (auto_loop_button, false, false);
 
                Frame* jpframe = manage (new Frame);
                HBox* jpbox = manage (new HBox);
 
                jpframe->add (*jpbox);
                jpframe->set_shadow_type (SHADOW_NONE);
-
+               
                jpbox->pack_start (play_selection_button, false, false);
                jpbox->pack_start (join_play_range_button, false, false);
                jpbox->pack_start (roll_button, false, false);
 
-               transport_hbox->pack_start (*jpframe, false, false);
+               tbox->pack_start (*jpframe, false, false);
+
+               Glib::RefPtr<SizeGroup> transport_button_size_group2 = SizeGroup::create (SIZE_GROUP_HORIZONTAL);
+               transport_button_size_group2->add_widget (play_selection_button);
+               transport_button_size_group2->add_widget (join_play_range_button);
+               transport_button_size_group2->add_widget (roll_button);
        }
-       transport_hbox->pack_start (stop_button, false, false);
-       transport_hbox->pack_start (rec_button, false, false, 6);
+
+       tbox->pack_start (stop_button, false, false);
+       tbox->pack_start (rec_button, false, false, 6);
 
        HBox* clock_box = manage (new HBox);
        clock_box->set_border_width (2);
-       primary_clock->main_display().set_ypad (2);
        primary_clock->set_border_width (2);
        clock_box->pack_start (*primary_clock, false, false);
        if (!ARDOUR::Profile->get_small_screen()) {
                secondary_clock->set_border_width (2);
-               secondary_clock->main_display().set_ypad (2);
                clock_box->pack_start (*secondary_clock, false, false);
        }
 
-       if (!Profile->get_sae()) {
-               VBox* time_controls_box = manage (new VBox);
-               time_controls_box->pack_start (sync_button, false, false);
-               time_controls_box->pack_start (time_master_button, false, false);
-               clock_box->pack_start (*time_controls_box, false, false, 1);
-       }
 
        shuttle_box = new ShuttleControl;
        shuttle_box->show ();
@@ -411,57 +392,53 @@ ARDOUR_UI::setup_transport ()
        transport_vbox->set_name ("TransportBase");
        transport_vbox->set_border_width (3);
        transport_vbox->set_spacing (3);
-       transport_vbox->pack_start (*transport_hbox, true, true, 0);
+       transport_vbox->pack_start (*tbox, true, true, 0);
        transport_vbox->pack_start (*shuttle_box, false, false, 0);
 
-       transport_tearoff_hbox.pack_start (*transport_vbox, false, false, 0);
-       transport_tearoff_hbox.pack_start (*clock_box, false, false, 0);
+       transport_tearoff_hbox.pack_start (*transport_vbox, false, false);
 
-       time_info_box = manage (new TimeInfoBox);
-       transport_tearoff_hbox.pack_start (*time_info_box, false, false);
+       /* transport related toggle controls */
 
        HBox* toggle_box = manage(new HBox);
-
-       VBox* punch_box = manage (new VBox);
-       punch_box->pack_start (punch_in_button, false, false);
-       punch_box->pack_start (punch_out_button, false, false);
-       toggle_box->pack_start (*punch_box, false, false);
-
        VBox* auto_box = manage (new VBox);
-       auto_box->pack_start (auto_play_button, false, false);
-       auto_box->pack_start (auto_return_button, false, false);
+       auto_box->set_spacing (2);
+       auto_box->set_homogeneous (true);
+       toggle_box->set_spacing (2);
+       toggle_box->set_homogeneous (true);
+       auto_box->pack_start (auto_play_button, true, false);
+       auto_box->pack_start (auto_return_button, true, false);
         if (!Profile->get_small_screen()) {
                 toggle_box->pack_start (*auto_box, false, false);
         }
+       transport_tearoff_hbox.pack_start (*toggle_box, false, false);
 
-       VBox* io_box = manage (new VBox);
-       io_box->pack_start (auto_input_button, false, false);
-       io_box->pack_start (click_button, false, false);
-        if (!Profile->get_small_screen()) {
-                toggle_box->pack_start (*io_box, false, false);
-        }
+       VBox* time_controls = manage (new VBox);
+       time_controls->set_spacing (2);
+       time_controls->set_homogeneous (true);
+       time_controls->pack_start (sync_button, true, false);
+       time_controls->pack_start (time_master_button, true, false);
 
-       /* desensitize */
-
-       set_transport_sensitivity (false);
+       transport_tearoff_hbox.pack_start (*clock_box, false, false);
+       transport_tearoff_hbox.pack_start (*time_controls, false, false);
+       transport_tearoff_hbox.pack_start (click_button, false, false);
 
-//     toggle_box->pack_start (preroll_button, false, false);
-//     toggle_box->pack_start (preroll_clock, false, false);
-
-//     toggle_box->pack_start (postroll_button, false, false);
-//     toggle_box->pack_start (postroll_clock, false, false);
+       time_info_box = manage (new TimeInfoBox);
+       transport_tearoff_hbox.pack_start (*time_info_box, false, false);
 
-       transport_tearoff_hbox.pack_start (*toggle_box, false, false, 4);
         if (Profile->get_small_screen()) {
-                transport_tearoff_hbox.pack_start (_editor_transport_box, false, false, 4);
+                transport_tearoff_hbox.pack_start (_editor_transport_box, false, false);
         }
        transport_tearoff_hbox.pack_start (alert_box, false, false);
 
        if (Profile->get_sae()) {
                Image* img = manage (new Image ((::get_icon (X_("sae")))));
-               transport_tearoff_hbox.pack_end (*img, false, false, 6);
+               transport_tearoff_hbox.pack_end (*img, false, false);
        }
 
+       /* desensitize */
+
+       set_transport_sensitivity (false);
+
        XMLNode* tnode = tearoff_settings ("transport");
        if (tnode) {
                transport_tearoff->set_state (*tnode);
@@ -559,7 +536,7 @@ ARDOUR_UI::sync_blink (bool onoff)
 {
        if (_session == 0 || !_session->config.get_external_sync()) {
                /* internal sync */
-               sync_button.set_visual_state (0);
+               sync_button.unset_active_state ();
                return;
        }
 
@@ -567,13 +544,13 @@ ARDOUR_UI::sync_blink (bool onoff)
                /* not locked, so blink on and off according to the onoff argument */
 
                if (onoff) {
-                       sync_button.set_visual_state (1); // "-active"
+                       sync_button.set_active_state (Gtkmm2ext::Active); // "-active"
                } else {
-                       sync_button.set_visual_state (0); // normal
+                       sync_button.unset_active_state (); // normal
                }
        } else {
                /* locked */
-               sync_button.set_visual_state (1); // "-active"
+                 sync_button.set_active_state (Gtkmm2ext::Active); // "-active"
        }
 }
 
@@ -586,13 +563,12 @@ ARDOUR_UI::audition_blink (bool onoff)
 
        if (_session->is_auditioning()) {
                if (onoff) {
-                       auditioning_alert_button.set_state (STATE_ACTIVE);
+                       auditioning_alert_button.set_active_state (Gtkmm2ext::Active);
                } else {
-                       auditioning_alert_button.set_state (STATE_NORMAL);
+                       auditioning_alert_button.unset_active_state();
                }
        } else {
-               auditioning_alert_button.set_active (false);
-               auditioning_alert_button.set_state (STATE_NORMAL);
+               auditioning_alert_button.unset_active_state ();
        }
 }