1 /* 2 * Copyright (C) 2005-2006 Taybin Rutkin <taybin@taybin.com> 3 * Copyright (C) 2005-2015 Paul Davis <paul@linuxaudiosystems.com> 4 * Copyright (C) 2006-2009 Sampo Savolainen <v2@iki.fi> 5 * Copyright (C) 2007-2015 David Robillard <d@drobilla.net> 6 * Copyright (C) 2009-2012 Carl Hetherington <carl@carlh.net> 7 * Copyright (C) 2013-2019 Robin Gareus <robin@gareus.org> 8 * Copyright (C) 2016-2017 Julien "_FrnchFrgg_" RIVAUD <frnchfrgg@free.fr> 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; either version 2 of the License, or 13 * (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License along 21 * with this program; if not, write to the Free Software Foundation, Inc., 22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 23 */ 24 25 #ifndef __ardour_plugin_ui_h__ 26 #define __ardour_plugin_ui_h__ 27 28 #ifdef WAF_BUILD 29 #include "gtk2ardour-config.h" 30 #endif 31 32 #include <vector> 33 #include <map> 34 #include <list> 35 36 #include <sigc++/signal.h> 37 38 #include <gtkmm/adjustment.h> 39 #include <gtkmm/box.h> 40 #include <gtkmm/button.h> 41 #include <gtkmm/eventbox.h> 42 #include <gtkmm/expander.h> 43 #include <gtkmm/filechooserbutton.h> 44 #include <gtkmm/image.h> 45 #include <gtkmm/label.h> 46 #include <gtkmm/menu.h> 47 #include <gtkmm/scrolledwindow.h> 48 #include <gtkmm/socket.h> 49 #include <gtkmm/table.h> 50 #include <gtkmm/togglebutton.h> 51 #include <gtkmm/viewport.h> 52 53 #include "ardour/types.h" 54 #include "ardour/plugin.h" 55 #include "ardour/variant.h" 56 57 #include "widgets/ardour_button.h" 58 #include "widgets/ardour_dropdown.h" 59 #include "widgets/ardour_spinner.h" 60 61 #include "ardour_window.h" 62 #include "automation_controller.h" 63 #include "pianokeyboard.h" 64 65 namespace ARDOUR { 66 class PluginInsert; 67 class Plugin; 68 class WindowsVSTPlugin; 69 class LXVSTPlugin; 70 class IOProcessor; 71 class AUPlugin; 72 class Processor; 73 } 74 75 namespace PBD { 76 class Controllable; 77 } 78 79 namespace ArdourWidgets { 80 class FastMeter; 81 } 82 83 class LatencyGUI; 84 class ArdourWindow; 85 class PluginEqGui; 86 class PluginLoadStatsGui; 87 class PluginPresetsUI; 88 class VSTPluginUI; 89 90 class PlugUIBase : public virtual sigc::trackable, public PBD::ScopedConnectionList 91 { 92 public: 93 PlugUIBase (boost::shared_ptr<ARDOUR::PluginInsert>); 94 virtual ~PlugUIBase(); 95 96 virtual gint get_preferred_height () = 0; 97 virtual gint get_preferred_width () = 0; resizable()98 virtual bool resizable () { return true; } 99 virtual bool start_updating(GdkEventAny*) = 0; 100 virtual bool stop_updating(GdkEventAny*) = 0; 101 activate()102 virtual void activate () {} deactivate()103 virtual void deactivate () {} 104 105 void update_preset_list (); 106 void update_preset (); 107 108 void latency_button_clicked (); 109 on_window_show(const std::string &)110 virtual bool on_window_show(const std::string& /*title*/) { return true; } on_window_hide()111 virtual void on_window_hide() {} 112 forward_key_event(GdkEventKey *)113 virtual void forward_key_event (GdkEventKey*) {} grab_focus()114 virtual void grab_focus () {} non_gtk_gui()115 virtual bool non_gtk_gui() const { return false; } 116 117 sigc::signal<void,bool> KeyboardFocused; 118 119 protected: 120 boost::shared_ptr<ARDOUR::PluginInsert> insert; 121 boost::shared_ptr<ARDOUR::Plugin> plugin; 122 123 void add_common_widgets (Gtk::HBox*, bool with_focus = true); 124 125 /* UI elements that subclasses can add to their widgets */ 126 127 /** a ComboBoxText which lists presets and manages their selection */ 128 ArdourWidgets::ArdourDropdown _preset_combo; 129 /** a label which has a * in if the current settings are different from the preset being shown */ 130 Gtk::Label _preset_modified; 131 /** a button to add a preset */ 132 ArdourWidgets::ArdourButton _add_button; 133 /** a button to save the current settings as a new user preset */ 134 ArdourWidgets::ArdourButton _save_button; 135 /** a button to delete the current preset (if it is a user one) */ 136 ArdourWidgets::ArdourButton _delete_button; 137 /** a button to show a preset browser */ 138 ArdourWidgets::ArdourButton _preset_browser_button; 139 /** a button to delete the reset the plugin params */ 140 ArdourWidgets::ArdourButton _reset_button; 141 /** a button to bypass the plugin */ 142 ArdourWidgets::ArdourButton _bypass_button; 143 /** and self-explaining button :) */ 144 ArdourWidgets::ArdourButton _pin_management_button; 145 /** a button to acquire keyboard focus */ 146 Gtk::EventBox _focus_button; 147 /** an expander containing the plugin description */ 148 Gtk::Expander description_expander; 149 /** an expander containing the plugin analysis graph */ 150 Gtk::Expander plugin_analysis_expander; 151 /** an expander containing the plugin cpu profile */ 152 Gtk::Expander cpuload_expander; 153 /** a button which, when clicked, opens the latency GUI */ 154 ArdourWidgets::ArdourButton _latency_button; 155 /** a button which sets all controls' automation setting to Manual */ 156 ArdourWidgets::ArdourButton automation_manual_all_button; 157 /** a button which sets all controls' automation setting to Play */ 158 ArdourWidgets::ArdourButton automation_play_all_button; 159 /** a button which sets all controls' automation setting to Write */ 160 ArdourWidgets::ArdourButton automation_write_all_button; 161 /** a button which sets all controls' automation setting to Touch */ 162 ArdourWidgets::ArdourButton automation_touch_all_button; 163 /** a button which sets all controls' automation setting to Latch */ 164 ArdourWidgets::ArdourButton automation_latch_all_button; 165 166 void set_latency_label (); 167 LatencyGUI* latency_gui; 168 ArdourWindow* latency_dialog; 169 170 PluginEqGui* eqgui; 171 PluginLoadStatsGui* stats_gui; 172 PluginPresetsUI* preset_gui; 173 ArdourWindow* preset_dialog; 174 175 int _no_load_preset; 176 177 virtual void preset_selected (ARDOUR::Plugin::PresetRecord preset); 178 void add_plugin_setting (); 179 void save_plugin_setting (); 180 void delete_plugin_setting (); 181 void reset_plugin_parameters (); 182 void browse_presets (); 183 void manage_pins (); 184 bool focus_toggled(GdkEventButton*); 185 bool bypass_button_release(GdkEventButton*); 186 void toggle_description (); 187 void toggle_plugin_analysis (); 188 void toggle_cpuload_display (); 189 void processor_active_changed (boost::weak_ptr<ARDOUR::Processor> p); 190 void plugin_going_away (); 191 void automation_state_changed (); 192 void preset_added_or_removed (); 193 void update_preset_modified (); 194 195 bool has_descriptive_presets () const; 196 197 PBD::ScopedConnection death_connection; 198 PBD::ScopedConnection active_connection; 199 PBD::ScopedConnection preset_added_connection; 200 PBD::ScopedConnection preset_removed_connection; 201 PBD::ScopedConnectionList control_connections; 202 203 private: 204 Gtk::Image* _focus_out_image; 205 Gtk::Image* _focus_in_image; 206 }; 207 208 class GenericPluginUI : public PlugUIBase, public Gtk::VBox 209 { 210 public: 211 GenericPluginUI (boost::shared_ptr<ARDOUR::PluginInsert> plug, bool scrollable=false); 212 ~GenericPluginUI (); 213 get_preferred_height()214 gint get_preferred_height () { return prefheight; } get_preferred_width()215 gint get_preferred_width () { return -1; } 216 217 bool start_updating(GdkEventAny*); 218 bool stop_updating(GdkEventAny*); 219 220 private: 221 Gtk::VBox main_contents; 222 Gtk::VBox settings_box; 223 Gtk::HBox hpacker; 224 Gtk::Menu* automation_menu; 225 226 gint prefheight; 227 bool is_scrollable; 228 229 struct MeterInfo { 230 ArdourWidgets::FastMeter* meter; 231 bool packed; 232 MeterInfoMeterInfo233 MeterInfo () { 234 meter = 0; 235 packed = false; 236 } 237 }; 238 239 /* FIXME: Unify with AutomationController */ 240 struct ControlUI : public Gtk::HBox { 241 parameterControlUI242 const Evoral::Parameter parameter() const { return param; } 243 244 Evoral::Parameter param; 245 boost::shared_ptr<ARDOUR::AutomationControl> control; 246 247 /* input */ 248 249 boost::shared_ptr<ARDOUR::ScalePoints> scale_points; 250 boost::shared_ptr<AutomationController> controller; 251 252 ArdourWidgets::ArdourButton automate_button; 253 Gtk::Label label; 254 ArdourWidgets::ArdourDropdown* combo; 255 Gtk::FileChooserButton* file_button; 256 ArdourWidgets::ArdourSpinner* spin_box; 257 258 bool button; 259 bool update_pending; 260 bool ignore_change; 261 262 263 /* output */ 264 265 Gtk::EventBox* display; 266 Gtk::Label* display_label; 267 268 Gtk::HBox* hbox; 269 Gtk::VBox* vbox; 270 MeterInfo* meterinfo; 271 272 ControlUI (const Evoral::Parameter& param); 273 ~ControlUI (); 274 275 /* layout */ 276 Gtk::Table* knobtable; 277 int x0, x1, y0, y1; 278 279 bool short_autostate; // modify with set_short_autostate below 280 }; 281 282 void set_short_autostate(ControlUI* cui, bool value); 283 284 std::vector<ControlUI*> input_controls; // workaround for preset load 285 std::vector<ControlUI*> input_controls_with_automation; 286 std::vector<ControlUI*> output_controls; 287 288 sigc::connection screen_update_connection; 289 290 void output_update(); 291 292 void build (); 293 void automatic_layout (const std::vector<ControlUI *>& control_uis); 294 295 ControlUI* build_control_ui (const Evoral::Parameter& param, 296 const ARDOUR::ParameterDescriptor& desc, 297 boost::shared_ptr<ARDOUR::AutomationControl> mcontrol, 298 float value, 299 bool is_input, 300 bool use_knob = false); 301 302 void ui_parameter_changed (ControlUI* cui); 303 void update_control_display (ControlUI* cui); 304 void update_input_displays (); // workaround for preset load 305 void control_combo_changed (ControlUI* cui, float value); 306 307 bool astate_button_event (GdkEventButton* ev, ControlUI*); 308 void automation_state_changed (ControlUI*); 309 void set_automation_state (ARDOUR::AutoState state, ControlUI* cui); 310 void set_all_automation (ARDOUR::AutoState state); 311 312 void knob_size_request(Gtk::Requisition* req, ControlUI* cui); 313 314 typedef std::map<uint32_t, Gtk::FileChooserButton*> FilePathControls; 315 FilePathControls _filepath_controls; 316 void set_path_property (const ARDOUR::ParameterDescriptor& desc, 317 Gtk::FileChooserButton* widget); 318 void path_property_changed (uint32_t key, const ARDOUR::Variant& value); 319 320 void scroller_size_request (Gtk::Requisition*); 321 Gtk::ScrolledWindow scroller; 322 323 Gtk::Expander _plugin_pianokeyboard_expander; 324 APianoKeyboard* _piano; 325 Gtk::VBox _pianobox; 326 Gtk::SpinButton _piano_velocity; 327 Gtk::SpinButton _piano_channel; 328 329 void note_on_event_handler (int, int); 330 void note_off_event_handler (int); 331 332 void toggle_pianokeyboard (); 333 void build_midi_table (); 334 void midi_refill_patches (); 335 void midi_bank_patch_change (uint8_t chn); 336 void midi_bank_patch_select (uint8_t chn, uint32_t bankpgm); 337 std::vector<ArdourWidgets::ArdourDropdown*> midi_pgmsel; 338 PBD::ScopedConnectionList midi_connections; 339 std::map<uint32_t, std::string> pgm_names; 340 }; 341 342 class PluginUIWindow : public ArdourWindow 343 { 344 public: 345 PluginUIWindow (boost::shared_ptr<ARDOUR::PluginInsert> insert, 346 bool scrollable=false, 347 bool editor=true); 348 ~PluginUIWindow (); 349 pluginui()350 PlugUIBase& pluginui() { return *_pluginui; } 351 352 void resize_preferred(); 353 void set_parent (Gtk::Window*); 354 void set_title(const std::string& title); 355 356 357 bool on_key_press_event (GdkEventKey*); 358 bool on_key_release_event (GdkEventKey*); 359 void on_show (); 360 void on_hide (); 361 362 private: 363 std::string _title; 364 PlugUIBase* _pluginui; 365 PBD::ScopedConnection death_connection; 366 Gtk::Window* parent; 367 Gtk::VBox vbox; 368 bool was_visible; 369 bool _keyboard_focused; 370 #ifdef AUDIOUNIT_SUPPORT 371 int pre_deactivate_x; 372 int pre_deactivate_y; 373 #endif 374 375 void keyboard_focused (bool yn); 376 377 void app_activated (bool); 378 void plugin_going_away (); 379 380 bool create_windows_vst_editor (boost::shared_ptr<ARDOUR::PluginInsert>); 381 bool create_lxvst_editor(boost::shared_ptr<ARDOUR::PluginInsert>); 382 bool create_mac_vst_editor(boost::shared_ptr<ARDOUR::PluginInsert>); 383 bool create_audiounit_editor (boost::shared_ptr<ARDOUR::PluginInsert>); 384 bool create_lv2_editor (boost::shared_ptr<ARDOUR::PluginInsert>); 385 bool create_vst3_editor (boost::shared_ptr<ARDOUR::PluginInsert>); 386 }; 387 388 #ifdef MACVST_SUPPORT 389 /* this function has to be in a .mm file 390 * because MacVSTPluginUI has Cocoa members 391 */ 392 extern VSTPluginUI* create_mac_vst_gui (boost::shared_ptr<ARDOUR::PluginInsert>); 393 #endif 394 395 #ifdef AUDIOUNIT_SUPPORT 396 /* this function has to be in a .mm file */ 397 extern PlugUIBase* create_au_gui (boost::shared_ptr<ARDOUR::PluginInsert>, Gtk::VBox**); 398 #endif 399 400 #endif /* __ardour_plugin_ui_h__ */ 401