consolidate engine-dialog widget sensitivity logic.
[ardour.git] / gtk2_ardour / engine_dialog.cc
index 01450ecb0b3a0b561442e84ed6ef96cb936792b9..555c804a6df2f5cfcfc7a17289e473dc15275b2e 100644 (file)
@@ -716,6 +716,81 @@ EngineControl::setup_midi_tab_for_backend ()
        midi_vbox.show_all ();
 }
 
+void
+EngineControl::update_sensitivity ()
+{
+       boost::shared_ptr<ARDOUR::AudioBackend> backend = ARDOUR::AudioEngine::instance()->current_backend();
+       if (!backend) {
+               ok_button->set_sensitive (false);
+               apply_button->set_sensitive (false);
+               return;
+       }
+
+       bool valid = true;
+       size_t devices_available = 0;
+
+       if (backend->use_separate_input_and_output_devices ()) {
+               devices_available += get_popdown_string_count (input_device_combo);
+               devices_available += get_popdown_string_count (output_device_combo);
+       } else {
+               devices_available += get_popdown_string_count (device_combo);
+       }
+
+       if (devices_available == 0) {
+               valid = false;
+               input_latency.set_sensitive (false);
+               output_latency.set_sensitive (false);
+               input_channels.set_sensitive (false);
+               output_channels.set_sensitive (false);
+       } else {
+               input_latency.set_sensitive (true);
+               output_latency.set_sensitive (true);
+               input_channels.set_sensitive (true);
+               output_channels.set_sensitive (true);
+       }
+
+       if (get_popdown_string_count (buffer_size_combo) > 0) {
+               if (!ARDOUR::AudioEngine::instance()->running()) {
+                       buffer_size_combo.set_sensitive (valid);
+               } else if (backend->can_change_sample_rate_when_running()) {
+                       buffer_size_combo.set_sensitive (valid || !_have_control);
+               } else {
+#if 1
+                       /* TODO
+                        * Currently there is no way to manually stop the
+                        * engine in order to re-configure it.
+                        * This needs to remain sensitive for now.
+                        */
+                       buffer_size_combo.set_sensitive (true);
+#else
+                       buffer_size_combo.set_sensitive (false);
+#endif
+               }
+       } else {
+               buffer_size_combo.set_sensitive (false);
+               valid = false;
+       }
+
+       if (get_popdown_string_count (sample_rate_combo) > 0) {
+               if (!ARDOUR::AudioEngine::instance()->running()) {
+                       sample_rate_combo.set_sensitive (true);
+               } else {
+                       sample_rate_combo.set_sensitive (false);
+               }
+       } else {
+               sample_rate_combo.set_sensitive (false);
+               valid = false;
+       }
+
+       if (valid || !_have_control) {
+               ok_button->set_sensitive (true);
+               apply_button->set_sensitive (true);
+       } else {
+               ok_button->set_sensitive (false);
+               apply_button->set_sensitive (false);
+       }
+}
+
 void
 EngineControl::setup_midi_tab_for_jack ()
 {
@@ -853,6 +928,12 @@ EngineControl::backend_changed ()
 
        started_at_least_once = false;
 
+       /* changing the backend implies stopping the engine
+        * ARDOUR::AudioEngine() may or may not emit this signal
+        * depending on previous engine state
+        */
+       engine_stopped (); // set "active/inactive"
+
        if (!ignore_changes) {
                maybe_display_saved_state ();
        }
@@ -1070,40 +1151,12 @@ EngineControl::list_devices ()
 
        if (devices_available) {
                device_changed ();
-
-               input_latency.set_sensitive (true);
-               output_latency.set_sensitive (true);
-               input_channels.set_sensitive (true);
-               output_channels.set_sensitive (true);
-
-               ok_button->set_sensitive (true);
-               apply_button->set_sensitive (true);
-
        } else {
                device_combo.clear();
                input_device_combo.clear();
                output_device_combo.clear();
-               sample_rate_combo.set_sensitive (false);
-               buffer_size_combo.set_sensitive (false);
-               input_latency.set_sensitive (false);
-               output_latency.set_sensitive (false);
-               input_channels.set_sensitive (false);
-               output_channels.set_sensitive (false);
-               if (_have_control) {
-                       ok_button->set_sensitive (false);
-                       apply_button->set_sensitive (false);
-               } else {
-                       ok_button->set_sensitive (true);
-                       apply_button->set_sensitive (true);
-                       if (backend->can_change_sample_rate_when_running() && sample_rate_combo.get_children().size() > 0) {
-                               sample_rate_combo.set_sensitive (true);
-                       }
-                       if (backend->can_change_buffer_size_when_running() && buffer_size_combo.get_children().size() > 0) {
-                               buffer_size_combo.set_sensitive (true);
-                       }
-
-               }
        }
+       update_sensitivity ();
 }
 
 void
@@ -1126,19 +1179,10 @@ EngineControl::get_sample_rates_for_all_devices ()
 {
        boost::shared_ptr<ARDOUR::AudioBackend> backend =
            ARDOUR::AudioEngine::instance ()->current_backend ();
-       vector<float> input_rates;
-       vector<float> output_rates;
        vector<float> all_rates;
 
        if (backend->use_separate_input_and_output_devices ()) {
-               input_rates = backend->available_sample_rates (get_input_device_name ());
-               output_rates = backend->available_sample_rates (get_output_device_name ());
-
-               std::set_union (input_rates.begin (),
-                               input_rates.end (),
-                               output_rates.begin (),
-                               output_rates.end (),
-                               std::back_inserter (all_rates));
+               all_rates = backend->available_sample_rates (get_input_device_name (), get_output_device_name ());
        } else {
                all_rates = backend->available_sample_rates (get_device_name ());
        }
@@ -1172,11 +1216,6 @@ EngineControl::set_samplerate_popdown_strings ()
 
        if (_have_control) {
                sr = get_sample_rates_for_all_devices ();
-               // currently possible if both devices are set to "None" and the backend
-               // returns no supported rates for both devices
-               if (sr.empty()) {
-                       sr = get_default_sample_rates ();
-               }
        } else {
                sr = get_default_sample_rates ();
        }
@@ -1188,10 +1227,9 @@ EngineControl::set_samplerate_popdown_strings ()
                }
        }
 
-       if (!s.empty()) {
-               sample_rate_combo.set_sensitive (true);
-               set_popdown_strings (sample_rate_combo, s);
+       set_popdown_strings (sample_rate_combo, s);
 
+       if (!s.empty()) {
                if (desired.empty ()) {
                        float new_active_sr = backend->default_sample_rate ();
 
@@ -1204,9 +1242,8 @@ EngineControl::set_samplerate_popdown_strings ()
                        sample_rate_combo.set_active_text (desired);
                }
 
-       } else {
-               sample_rate_combo.set_sensitive (false);
        }
+       update_sensitivity ();
 }
 
 vector<uint32_t>
@@ -1214,19 +1251,10 @@ EngineControl::get_buffer_sizes_for_all_devices ()
 {
        boost::shared_ptr<ARDOUR::AudioBackend> backend =
            ARDOUR::AudioEngine::instance ()->current_backend ();
-       vector<uint32_t> input_sizes;
-       vector<uint32_t> output_sizes;
        vector<uint32_t> all_sizes;
 
        if (backend->use_separate_input_and_output_devices ()) {
-               input_sizes = backend->available_buffer_sizes (get_input_device_name ());
-               output_sizes = backend->available_buffer_sizes (get_output_device_name ());
-
-               std::set_union (input_sizes.begin (),
-                               input_sizes.end (),
-                               output_sizes.begin (),
-                               output_sizes.end (),
-                               std::back_inserter (all_sizes));
+               all_sizes = backend->available_buffer_sizes (get_input_device_name (), get_output_device_name ());
        } else {
                all_sizes = backend->available_buffer_sizes (get_device_name ());
        }
@@ -1258,15 +1286,9 @@ EngineControl::set_buffersize_popdown_strings ()
        boost::shared_ptr<ARDOUR::AudioBackend> backend = ARDOUR::AudioEngine::instance()->current_backend();
        vector<uint32_t> bs;
        vector<string> s;
-       string device_name;
 
        if (_have_control) {
                bs = get_buffer_sizes_for_all_devices ();
-               // currently possible if both devices are set to "None" and the backend
-               // returns no supported sizes for both devices
-               if (bs.empty()) {
-                       bs = get_default_buffer_sizes ();
-               }
        } else if (backend->can_change_buffer_size_when_running()) {
                bs = get_default_buffer_sizes ();
        }
@@ -1275,26 +1297,26 @@ EngineControl::set_buffersize_popdown_strings ()
                s.push_back (bufsize_as_string (*x));
        }
 
-       if (backend->use_separate_input_and_output_devices ()) {
-               device_name = get_input_device_name ();
-       } else {
-               device_name = get_device_name ();
-       }
+       set_popdown_strings (buffer_size_combo, s);
 
        if (!s.empty()) {
-               buffer_size_combo.set_sensitive (true);
-               set_popdown_strings (buffer_size_combo, s);
                buffer_size_combo.set_active_text (s.front());
 
                uint32_t period = backend->buffer_size();
-               if (0 == period) {
-                       period = backend->default_buffer_size(device_name);
+               if (0 == period && backend->use_separate_input_and_output_devices ()) {
+                       period = backend->default_buffer_size (get_input_device_name ());
                }
+               if (0 == period && backend->use_separate_input_and_output_devices ()) {
+                       period = backend->default_buffer_size (get_output_device_name ());
+               }
+               if (0 == period && !backend->use_separate_input_and_output_devices ()) {
+                       period = backend->default_buffer_size (get_device_name ());
+               }
+
                set_active_text_if_present (buffer_size_combo, bufsize_as_string (period));
                show_buffer_duration ();
-       } else {
-               buffer_size_combo.set_sensitive (false);
        }
+       update_sensitivity ();
 }
 
 void
@@ -1343,13 +1365,10 @@ EngineControl::device_changed ()
                 */
                PBD::Unwinder<uint32_t> protect_ignore_changes (ignore_changes, ignore_changes + 1);
 
-               /* backends that support separate devices, need to ignore
-                * the device-name - and use the devies set above
-                */
                set_samplerate_popdown_strings ();
                set_buffersize_popdown_strings ();
-               /* XXX theoretically need to set min + max channel counts here
-               */
+
+               /* TODO set min + max channel counts here */
 
                manage_control_app_sensitivity ();
        }
@@ -2416,9 +2435,8 @@ EngineControl::on_switch_page (GtkNotebookPage*, guint page_num)
 {
        if (page_num == 0) {
                cancel_button->set_sensitive (true);
-               ok_button->set_sensitive (true);
-               apply_button->set_sensitive (true);
                _measure_midi.reset();
+               update_sensitivity ();
        } else {
                cancel_button->set_sensitive (false);
                ok_button->set_sensitive (false);
@@ -2700,14 +2718,12 @@ EngineControl::engine_running ()
        set_active_text_if_present (buffer_size_combo, bufsize_as_string (backend->buffer_size()));
        sample_rate_combo.set_active_text (rate_as_string (backend->sample_rate()));
 
-       buffer_size_combo.set_sensitive (true);
-       sample_rate_combo.set_sensitive (true);
-
        connect_disconnect_button.set_label (string_compose (_("Disconnect from %1"), backend->name()));
        connect_disconnect_button.show();
 
        started_at_least_once = true;
        engine_status.set_markup(string_compose ("<span foreground=\"green\">%1</span>", _("Active")));
+       update_sensitivity();
 }
 
 void
@@ -2716,13 +2732,16 @@ EngineControl::engine_stopped ()
        boost::shared_ptr<ARDOUR::AudioBackend> backend = ARDOUR::AudioEngine::instance()->current_backend();
        assert (backend);
 
-       buffer_size_combo.set_sensitive (false);
        connect_disconnect_button.set_label (string_compose (_("Connect to %1"), backend->name()));
        connect_disconnect_button.show();
 
-       sample_rate_combo.set_sensitive (true);
-       buffer_size_combo.set_sensitive (true);
-       engine_status.set_markup(string_compose ("<span foreground=\"red\">%1</span>", _("Inactive")));
+       if (ARDOUR::Profile->get_mixbus()) {
+               engine_status.set_markup("");
+       } else {
+               engine_status.set_markup(string_compose ("<span foreground=\"red\">%1</span>", _("Inactive")));
+       }
+
+       update_sensitivity();
 }
 
 void