From fc07a92d36e2d021abd576d5d6108da826d2fd05 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Tue, 20 Aug 2024 20:01:06 +0200 Subject: [PATCH] Prepare GUI for missing (stub) RegionFx --- gtk2_ardour/audio_region_editor.cc | 4 ++ gtk2_ardour/region_editor.cc | 111 ++++++++++++++++------------- gtk2_ardour/region_editor.h | 3 +- 3 files changed, 69 insertions(+), 49 deletions(-) diff --git a/gtk2_ardour/audio_region_editor.cc b/gtk2_ardour/audio_region_editor.cc index 0991626eb5..c1aea81769 100644 --- a/gtk2_ardour/audio_region_editor.cc +++ b/gtk2_ardour/audio_region_editor.cc @@ -302,6 +302,10 @@ AudioRegionEditor::refill_region_line () } std::shared_ptr plugin = fx->plugin (); + if (!plugin) { + return; + } + Gtk::Menu* acm = manage (new Gtk::Menu); MenuList& acm_items (acm->items ()); diff --git a/gtk2_ardour/region_editor.cc b/gtk2_ardour/region_editor.cc index 73572c8c0b..44a832dcd2 100644 --- a/gtk2_ardour/region_editor.cc +++ b/gtk2_ardour/region_editor.cc @@ -636,51 +636,53 @@ RegionEditor::RegionFxBox::fxe_button_press_event (GdkEventButton* ev, RegionFxE std::shared_ptr plugin = child->region_fx_plugin ()->plugin (); - items.push_back (SeparatorElem ()); - items.push_back (MenuElem (_("Edit..."), sigc::bind (sigc::mem_fun (*this, &RegionFxBox::show_plugin_gui), wfx, true))); - items.back ().set_sensitive (plugin->has_editor ()); - items.push_back (MenuElem (_("Edit with generic controls..."), sigc::bind (sigc::mem_fun (*this, &RegionFxBox::show_plugin_gui), wfx, false))); - - Gtk::Menu* automation_menu = manage (new Gtk::Menu); - MenuList& ac_items (automation_menu->items ()); - - for (size_t i = 0; i < plugin->parameter_count (); ++i) { - if (!plugin->parameter_is_control (i) || !plugin->parameter_is_input (i)) { - continue; - } - const Evoral::Parameter param (PluginAutomation, 0, i); - std::string label = plugin->describe_parameter (param); - if (label == X_("latency") || label == X_("hidden")) { - continue; - } - std::shared_ptr c (std::dynamic_pointer_cast (child->region_fx_plugin ()->control (param))); - if (c && c->flags () & (Controllable::HiddenControl | Controllable::NotAutomatable)) { - continue; - } - - std::weak_ptr wac (c); - bool play = c->automation_state () == Play; - - ac_items.push_back (CheckMenuElem (label)); - Gtk::CheckMenuItem* cmi = static_cast (&ac_items.back ()); - cmi->set_active (play); - cmi->signal_activate ().connect ([wac, play] () { - std::shared_ptr ac = wac.lock (); - if (ac) { - ac->set_automation_state (play ? ARDOUR::Off : Play); - } - }); - } - - if (!ac_items.empty ()) { + if (plugin) { + items.push_back (SeparatorElem ()); + items.push_back (MenuElem (_("Edit..."), sigc::bind (sigc::mem_fun (*this, &RegionFxBox::show_plugin_gui), wfx, true))); + items.back ().set_sensitive (plugin->has_editor ()); + items.push_back (MenuElem (_("Edit with generic controls..."), sigc::bind (sigc::mem_fun (*this, &RegionFxBox::show_plugin_gui), wfx, false))); + + Gtk::Menu* automation_menu = manage (new Gtk::Menu); + MenuList& ac_items (automation_menu->items ()); + + for (size_t i = 0; i < plugin->parameter_count (); ++i) { + if (!plugin->parameter_is_control (i) || !plugin->parameter_is_input (i)) { + continue; + } + const Evoral::Parameter param (PluginAutomation, 0, i); + std::string label = plugin->describe_parameter (param); + if (label == X_("latency") || label == X_("hidden")) { + continue; + } + std::shared_ptr c (std::dynamic_pointer_cast (child->region_fx_plugin ()->control (param))); + if (c && c->flags () & (Controllable::HiddenControl | Controllable::NotAutomatable)) { + continue; + } + + std::weak_ptr wac (c); + bool play = c->automation_state () == Play; + + ac_items.push_back (CheckMenuElem (label)); + Gtk::CheckMenuItem* cmi = static_cast (&ac_items.back ()); + cmi->set_active (play); + cmi->signal_activate ().connect ([wac, play] () { + std::shared_ptr ac = wac.lock (); + if (ac) { + ac->set_automation_state (play ? ARDOUR::Off : Play); + } + }); + } + + if (!ac_items.empty ()) { + items.push_back (SeparatorElem ()); + items.push_back (MenuElem (_("Automation Enable"), *automation_menu)); + items.push_back (MenuElem (_("Clear All Automation"), sigc::bind (sigc::mem_fun (*this, &RegionFxBox::clear_automation), wfx))); + } else { + delete automation_menu; + } items.push_back (SeparatorElem ()); - items.push_back (MenuElem (_("Automation Enable"), *automation_menu)); - items.push_back (MenuElem (_("Clear All Automation"), sigc::bind (sigc::mem_fun (*this, &RegionFxBox::clear_automation), wfx))); - } else { - delete automation_menu; } - items.push_back (SeparatorElem ()); items.push_back (MenuElem (_("Delete"), sigc::bind (sigc::mem_fun (*this, &RegionFxBox::queue_delete_region_fx), wfx))); m->signal_unmap ().connect ([this, &npm] () { npm.remove_submenu (); _display.remove_placeholder (); }); @@ -962,7 +964,7 @@ void RegionEditor::RegionFxBox::show_plugin_gui (std::weak_ptr wfx, bool custom_ui) { std::shared_ptr rfx (wfx.lock ()); - if (!rfx) { + if (!rfx || !rfx->plugin ()) { return; } @@ -1001,18 +1003,29 @@ RegionEditor::RegionFxEntry::RegionFxEntry (std::shared_ptr rfx, { _box.pack_start (_fx_btn, true, true); - _plugin_preset_pointer = PluginPresetPtr (new PluginPreset (rfx->plugin ()->get_info ())); + if (rfx->plugin ()) { + _plugin_preset_pointer = PluginPresetPtr (new PluginPreset (rfx->plugin ()->get_info ())); + _selectable = true; + } else { + _plugin_preset_pointer = 0; + _selectable = false; + } _fx_btn.set_fallthrough_to_parent (true); _fx_btn.set_text (name ()); _fx_btn.set_active (true); - if (pre) { + + if (!_selectable) { + _fx_btn.set_name ("processor stub"); + } else if (pre) { _fx_btn.set_name ("processor prefader"); } else { _fx_btn.set_name ("processor postfader"); } - if (rfx->plugin ()->has_editor ()) { + if (!rfx->plugin ()) { + set_tooltip (_fx_btn, string_compose (_("%1\nThe Plugin is not available on this system\nand has been replaced by a stub."), name ())); + } else if (rfx->plugin ()->has_editor ()) { set_tooltip (_fx_btn, string_compose (_("%1\nDouble-click to show GUI.\n%2+double-click to show generic GUI."), name (), Keyboard::secondary_modifier_name ())); } else { set_tooltip (_fx_btn, string_compose (_("%1\nDouble-click to show generic GUI."), name ())); @@ -1043,7 +1056,7 @@ RegionEditor::RegionFxEntry::can_copy_state (Gtkmm2ext::DnDVBoxChild* o) const } std::shared_ptr my_p = self->plugin (); std::shared_ptr ot_p = othr->plugin (); - return my_p->unique_id () == ot_p->unique_id (); + return my_p && ot_p && my_p->unique_id () == ot_p->unique_id (); } void @@ -1065,7 +1078,9 @@ RegionEditor::RegionFxEntry::drag_data_get (Glib::RefPtr const } std::shared_ptr plugin = _rfx->plugin (); - assert (plugin); + if (!plugin) { + return false; + } PluginManager& manager (PluginManager::instance ()); bool fav = manager.get_status (_plugin_preset_pointer->_pip) == PluginManager::Favorite; diff --git a/gtk2_ardour/region_editor.h b/gtk2_ardour/region_editor.h index 5bd365456e..86952592f3 100644 --- a/gtk2_ardour/region_editor.h +++ b/gtk2_ardour/region_editor.h @@ -80,7 +80,7 @@ private: Gtk::EventBox& action_widget () { return _fx_btn; } Gtk::Widget& widget () { return _box; } std::string drag_text () const { return name (); } - bool is_selectable() const { return true; } + bool is_selectable() const { return _selectable; } bool can_copy_state (Gtkmm2ext::DnDVBoxChild*) const; void set_visual_state (Gtkmm2ext::VisualState, bool); bool drag_data_get (Glib::RefPtr const, Gtk::SelectionData &); @@ -93,6 +93,7 @@ private: ArdourWidgets::ArdourButton _fx_btn; std::shared_ptr _rfx; ARDOUR::PluginPresetPtr _plugin_preset_pointer; + bool _selectable; }; class RegionFxBox : public Gtk::VBox, public PluginInterestedObject //, public ARDOUR::SessionHandlePtr