Improvements to the plugin eq gui:
[ardour.git] / gtk2_ardour / plugin_ui.cc
index ceb31561cd3514e344e420d6ab889261d3f42f49..bfac04aa9b4d71c12f6b4ef46bfed1a42a79ae48 100644 (file)
@@ -22,9 +22,9 @@
 #include <cmath>
 #include <string>
 
-#include <pbd/stl_delete.h>
-#include <pbd/xml++.h>
-#include <pbd/failed_constructor.h>
+#include "pbd/stl_delete.h"
+#include "pbd/xml++.h"
+#include "pbd/failed_constructor.h"
 
 #include <gtkmm/widget.h>
 #include <gtkmm/box.h>
 #include <gtkmm2ext/doi.h>
 #include <gtkmm2ext/slider_controller.h>
 
-#include <midi++/manager.h>
+#include "midi++/manager.h"
 
-#include <ardour/plugin.h>
-#include <ardour/plugin_insert.h>
-#include <ardour/ladspa_plugin.h>
+#include "ardour/plugin.h"
+#include "ardour/plugin_insert.h"
+#include "ardour/ladspa_plugin.h"
 #ifdef VST_SUPPORT
-#include <ardour/vst_plugin.h>
+#include "ardour/vst_plugin.h"
 #endif
 #ifdef HAVE_LV2
-#include <ardour/lv2_plugin.h>
+#include "ardour/lv2_plugin.h"
 #include "lv2_plugin_ui.h"
 #endif
 
@@ -57,7 +57,7 @@
 #include "gui_thread.h"
 #include "public_editor.h"
 #include "keyboard.h"
-#include "eq_gui.h"
+#include "plugin_eq_gui.h"
 
 #include "i18n.h"
 
@@ -114,14 +114,16 @@ PluginUIWindow::PluginUIWindow (Gtk::Window* win, boost::shared_ptr<PluginInsert
                GenericPluginUI*  pu  = new GenericPluginUI (insert, scrollable);
                
                _pluginui = pu;
-       
+               add( *pu );
+
+               /*
                Gtk::HBox *hbox = new Gtk::HBox();
                hbox->pack_start( *pu);
                // TODO: this should be nicer
-               hbox->pack_start( *manage(new PluginEqGui(insert)));
+               hbox->pack_start( eqgui_bin );
                
                add (*manage(hbox));
-
+               */
 
                set_wmclass (X_("ardour_plugin_editor"), "Ardour");
 
@@ -182,6 +184,22 @@ PluginUIWindow::on_leave_notify_event (GdkEventCrossing *ev)
        return false;
 }
 
+bool
+PluginUIWindow::on_focus_in_event (GdkEventFocus *ev)
+{
+       Window::on_focus_in_event (ev);
+       //Keyboard::the_keyboard().magic_widget_grab_focus ();
+       return false;
+}
+
+bool
+PluginUIWindow::on_focus_out_event (GdkEventFocus *ev)
+{
+       Window::on_focus_out_event (ev);
+       //Keyboard::the_keyboard().magic_widget_drop_focus ();
+       return false;
+}
+
 void
 PluginUIWindow::on_show ()
 {
@@ -294,10 +312,6 @@ PluginUIWindow::create_lv2_editor(boost::shared_ptr<PluginInsert> insert)
 bool
 PluginUIWindow::on_key_press_event (GdkEventKey* event)
 {
-       if (non_gtk_gui) {
-               return false;
-       }
-
        if (!key_press_focus_accelerator_handler (*this, event)) {
                return PublicEditor::instance().on_key_press_event(event);
        } else {
@@ -327,10 +341,11 @@ PlugUIBase::PlugUIBase (boost::shared_ptr<PluginInsert> pi)
          plugin (insert->plugin()),
          save_button(_("Add")),
          bypass_button (_("Bypass")),
-         latency_gui (*pi, pi->session().frame_rate(), pi->session().get_block_size())
+         latency_gui (*pi, pi->session().frame_rate(), pi->session().get_block_size()),
+         eqgui_toggle (_("Freq Analysis"))
 {
-        //preset_combo.set_use_arrows_always(true);
-       set_popdown_strings (preset_combo, plugin->get_presets());
+       //preset_combo.set_use_arrows_always(true);
+       update_presets();
        preset_combo.set_size_request (100, -1);
        preset_combo.set_active_text ("");
        preset_combo.signal_changed().connect(mem_fun(*this, &PlugUIBase::setting_selected));
@@ -341,11 +356,31 @@ PlugUIBase::PlugUIBase (boost::shared_ptr<PluginInsert> pi)
        insert->ActiveChanged.connect (bind(
                        mem_fun(*this, &PlugUIBase::processor_active_changed),
                        boost::weak_ptr<Processor>(insert)));
+
+       eqgui_toggle.set_active (false);
+       eqgui_toggle.signal_toggled().connect( mem_fun(*this, &PlugUIBase::toggle_plugin_analysis));
+
        
        bypass_button.set_active (!pi->active());
 
        bypass_button.set_name ("PluginBypassButton");
        bypass_button.signal_toggled().connect (mem_fun(*this, &PlugUIBase::bypass_toggled));
+       focus_button.add_events (Gdk::ENTER_NOTIFY_MASK|Gdk::LEAVE_NOTIFY_MASK);
+
+       focus_button.signal_button_release_event().connect (mem_fun(*this, &PlugUIBase::focus_toggled));
+       focus_button.add_events (Gdk::ENTER_NOTIFY_MASK|Gdk::LEAVE_NOTIFY_MASK);
+
+       /* these images are not managed, so that we can remove them at will */
+
+       focus_out_image = new Image (get_icon (X_("computer_keyboard")));
+       focus_in_image = new Image (get_icon (X_("computer_keyboard_active")));
+       
+       focus_button.add (*focus_out_image);
+
+       ARDOUR_UI::instance()->set_tip (&focus_button, _("Click to focus all keyboard events on this plugin window"), "");
+       ARDOUR_UI::instance()->set_tip (&bypass_button, _("Click to enable/disable this plugin"), "");
+
+       plugin_eq_bin.set_expanded(true);
 }
 
 void
@@ -362,8 +397,12 @@ void
 PlugUIBase::setting_selected()
 {
        if (preset_combo.get_active_text().length() > 0) {
-               if (!plugin->load_preset(preset_combo.get_active_text())) {
-                       warning << string_compose(_("Plugin preset %1 not found"), preset_combo.get_active_text()) << endmsg;
+               const Plugin::PresetRecord* pr = plugin->preset_by_label(preset_combo.get_active_text());
+               if (pr) {
+                       plugin->load_preset(pr->uri);
+               } else {
+                       warning << string_compose(_("Plugin preset %1 not found"),
+                                       preset_combo.get_active_text()) << endmsg;
                }
        }
 }
@@ -375,19 +414,17 @@ PlugUIBase::save_plugin_setting ()
        prompter.set_prompt(_("Name of New Preset:"));
        prompter.add_button (Gtk::Stock::ADD, Gtk::RESPONSE_ACCEPT);
        prompter.set_response_sensitive (Gtk::RESPONSE_ACCEPT, false);
+       prompter.set_type_hint (Gdk::WINDOW_TYPE_HINT_UTILITY);
 
        prompter.show_all();
 
        switch (prompter.run ()) {
        case Gtk::RESPONSE_ACCEPT:
-
                string name;
-
                prompter.get_result(name);
-
                if (name.length()) {
-                       if(plugin->save_preset(name)){
-                               set_popdown_strings (preset_combo, plugin->get_presets());
+                       if (plugin->save_preset(name)) {
+                               update_presets();
                                preset_combo.set_active_text (name);
                        }
                }
@@ -401,17 +438,79 @@ PlugUIBase::bypass_toggled ()
        bool x;
 
        if ((x = bypass_button.get_active()) == insert->active()) {
-               insert->set_active (!x);
-               if (insert->active()) {
-                       bypass_button.set_label (_("Bypass"));
+               if (x) {
+                       insert->deactivate ();
                } else {
-                       bypass_button.set_label (_("Active"));
+                       insert->activate ();
                }
        }
 }
 
+bool
+PlugUIBase::focus_toggled (GdkEventButton* ev)
+{
+       if (Keyboard::the_keyboard().some_magic_widget_has_focus()) {
+               Keyboard::the_keyboard().magic_widget_drop_focus();
+               focus_button.remove ();
+               focus_button.add (*focus_out_image);
+               focus_out_image->show ();
+               ARDOUR_UI::instance()->set_tip (&focus_button, _("Click to focus all keyboard events on this plugin window"), "");
+       } else {
+               Keyboard::the_keyboard().magic_widget_grab_focus();
+               focus_button.remove ();
+               focus_button.add (*focus_in_image);
+               focus_in_image->show ();
+               ARDOUR_UI::instance()->set_tip (&focus_button, _("Click to remove keyboard focus from this plugin window"), "");
+       }
+
+       return true;
+}
+
+void
+PlugUIBase::toggle_plugin_analysis()
+{
+       if (eqgui_toggle.get_active() && !plugin_eq_bin.get_child()) {
+               // Create the GUI
+               PluginEqGui *foo = new PluginEqGui(insert);
+               plugin_eq_bin.add( *foo );
+               plugin_eq_bin.show_all();
+       } 
+       
+       Gtk::Widget *gui;
+
+       if (!eqgui_toggle.get_active() && (gui = plugin_eq_bin.get_child())) {
+               // Hide & remove
+               gui->hide();
+               //plugin_eq_bin.remove(*gui);
+               plugin_eq_bin.remove();
+
+               delete gui;
+
+               Gtk::Widget *toplevel = plugin_eq_bin.get_toplevel();
+               if (!toplevel) {
+                       std::cerr << "No toplevel widget?!?!" << std::endl;
+                       return;
+               }
+
+               Gtk::Container *cont = dynamic_cast<Gtk::Container *>(toplevel);
+               if (!cont) {
+                       std::cerr << "Toplevel widget is not a container?!?" << std::endl;
+                       return;
+               }
+
+               Gtk::Allocation alloc(0, 0, 50, 50); // Just make it small
+               toplevel->size_allocate(alloc);
+       }
+}
+
 void
 PlugUIBase::update_presets ()
 {
-       set_popdown_strings (preset_combo, plugin->get_presets());
+       vector<string> preset_labels;
+       vector<ARDOUR::Plugin::PresetRecord> presets = plugin->get_presets();
+       for (vector<ARDOUR::Plugin::PresetRecord>::const_iterator i = presets.begin();
+                  i != presets.end(); ++i) {
+               preset_labels.push_back(i->label);
+       }
+       set_popdown_strings (preset_combo, preset_labels);
 }