From 938e1dc7e24f6b4e7e14aa7b78fe42b3eb5b056c Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Wed, 11 Dec 2024 03:03:03 +0100 Subject: [PATCH] Show RegionFX plugin UI in Selection Property Box --- gtk2_ardour/region_fx_properties_box.cc | 154 ++++++++++++++++++++++++ gtk2_ardour/region_fx_properties_box.h | 61 ++++++++++ gtk2_ardour/selection_properties_box.cc | 17 ++- gtk2_ardour/selection_properties_box.h | 12 +- gtk2_ardour/wscript | 1 + 5 files changed, 236 insertions(+), 9 deletions(-) create mode 100644 gtk2_ardour/region_fx_properties_box.cc create mode 100644 gtk2_ardour/region_fx_properties_box.h diff --git a/gtk2_ardour/region_fx_properties_box.cc b/gtk2_ardour/region_fx_properties_box.cc new file mode 100644 index 0000000000..73fa11e67e --- /dev/null +++ b/gtk2_ardour/region_fx_properties_box.cc @@ -0,0 +1,154 @@ +/* + * Copyright (C) 2024 Robin Gareus + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include + +#include "pbd/compose.h" + +#include "gtkmm2ext/gui_thread.h" +#include "gtkmm2ext/utils.h" + +#include "widgets/frame.h" + +#include "ardour/region.h" +#include "ardour/region_fx_plugin.h" +#include "plugin_ui.h" +#include "region_fx_properties_box.h" +#include "timers.h" +#include "ui_config.h" + +#include "pbd/i18n.h" + +using namespace Gtk; +using namespace ARDOUR; +using namespace ArdourWidgets; + +RegionFxPropertiesBox::RegionFxPropertiesBox (std::shared_ptr r) + : _region (r) + , _idle_redisplay_plugins_id (-1) +{ + _scroller.set_policy (Gtk::POLICY_AUTOMATIC, Gtk::POLICY_NEVER); + _scroller.set_shadow_type(Gtk::SHADOW_NONE); + _scroller.set_border_width(0); + _scroller.add (_box); + + _box.set_spacing (4); + + pack_start (_scroller, true, true); + show_all(); + + /* remove shadow from scrollWindow's viewport */ + Gtk::Viewport* viewport = (Gtk::Viewport*) _scroller.get_child(); + viewport->set_shadow_type(Gtk::SHADOW_NONE); + viewport->set_border_width(0); + + _region->RegionFxChanged.connect (_region_connection, invalidator (*this), std::bind (&RegionFxPropertiesBox::idle_redisplay_plugins, this), gui_context ()); + + redisplay_plugins (); +} + +RegionFxPropertiesBox::~RegionFxPropertiesBox () +{ + drop_plugin_uis (); + + if (_idle_redisplay_plugins_id >= 0) { + g_source_destroy (g_main_context_find_source_by_id (NULL, _idle_redisplay_plugins_id)); + _idle_redisplay_plugins_id = -1; + } +} + +void +RegionFxPropertiesBox::drop_plugin_uis () +{ + std::list children = _box.get_children (); + for (auto const& child : children) { + child->hide (); + _box.remove (*child); + delete child; + } + + for (auto const& ui : _proc_uis) { + ui->stop_updating (0); + delete ui; + } + + _processor_connections.drop_connections (); + _proc_uis.clear (); +} + +void +RegionFxPropertiesBox::add_fx_to_display (std::weak_ptr wfx) +{ + std::shared_ptr fx (wfx.lock ()); + if (!fx || !fx->plugin ()) { + return; + } + + GenericPluginUI* plugin_ui = new GenericPluginUI (fx, true, true); + if (plugin_ui->empty ()) { + delete plugin_ui; + return; + } + _proc_uis.push_back (plugin_ui); + + ArdourWidgets::Frame* frame = new ArdourWidgets::Frame (); + frame->set_label (fx->name ()); + frame->add (*plugin_ui); + frame->set_padding (0); + frame->set_edge_color (0x000000ff); // black (0); + _box.pack_start (*frame, false, false); + plugin_ui->show (); +} + +int +RegionFxPropertiesBox::_idle_redisplay_processors (gpointer arg) +{ + static_cast(arg)->redisplay_plugins (); + return 0; +} + +void +RegionFxPropertiesBox::idle_redisplay_plugins () +{ + if (_idle_redisplay_plugins_id < 0) { + _idle_redisplay_plugins_id = g_idle_add_full (G_PRIORITY_HIGH_IDLE + 10, _idle_redisplay_processors, this, NULL); + } +} + +void +RegionFxPropertiesBox::redisplay_plugins () +{ + drop_plugin_uis (); + + _region->foreach_plugin (sigc::mem_fun (*this, &RegionFxPropertiesBox::add_fx_to_display)); + + if (_proc_uis.empty ()) { + _scroller.hide (); + } else { + float ui_scale = std::max (1.f, UIConfiguration::instance().get_ui_scale()); + int h = 100 * ui_scale; + for (auto const& ui : _proc_uis) { + h = std::max (h, ui->get_preferred_height () + /* frame label */ 30 * ui_scale); + } + h = std::min (h, 300 * ui_scale); + _box.set_size_request (-1, h); + _scroller.show_all (); + } + _idle_redisplay_plugins_id = -1; +} diff --git a/gtk2_ardour/region_fx_properties_box.h b/gtk2_ardour/region_fx_properties_box.h new file mode 100644 index 0000000000..26615ce27b --- /dev/null +++ b/gtk2_ardour/region_fx_properties_box.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2024 Robin Gareus + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#pragma once + +#include + +#include +#include + +#include "ardour/ardour.h" +#include "ardour/session_handle.h" + +namespace ARDOUR { + class RegionFxPlugin; + class Region; +} + +class GenericPluginUI; + +class RegionFxPropertiesBox : public Gtk::HBox +{ +public: + RegionFxPropertiesBox (std::shared_ptr); + ~RegionFxPropertiesBox (); + +private: + void drop_plugin_uis (); + void redisplay_plugins (); + void add_fx_to_display (std::weak_ptr); + void idle_redisplay_plugins (); + + static int _idle_redisplay_processors (gpointer); + + Gtk::ScrolledWindow _scroller; + Gtk::HBox _box; + + std::shared_ptr _region; + std::vector _proc_uis; + + int _idle_redisplay_plugins_id; + + PBD::ScopedConnectionList _processor_connections; + PBD::ScopedConnection _region_connection; + sigc::connection screen_update_connection; +}; diff --git a/gtk2_ardour/selection_properties_box.cc b/gtk2_ardour/selection_properties_box.cc index 2631f2ac72..80cdbf8fe8 100644 --- a/gtk2_ardour/selection_properties_box.cc +++ b/gtk2_ardour/selection_properties_box.cc @@ -28,6 +28,7 @@ #include "audio_region_editor.h" #include "audio_region_view.h" #include "editor.h" +#include "region_fx_properties_box.h" #include "region_view.h" #include "route_properties_box.h" #include "selection_properties_box.h" @@ -42,6 +43,7 @@ using std::max; SelectionPropertiesBox::SelectionPropertiesBox () : _region_editor (nullptr) + , _region_fx_box (nullptr) { init (); @@ -50,11 +52,12 @@ SelectionPropertiesBox::SelectionPropertiesBox () pack_start(*_time_info_box, false, false, 0); pack_start(*_route_prop_box, true, true, 0); - pack_start(_region_editor_box, false, false, 0); + pack_start(_region_editor_box, true, true, 0); _time_info_box->set_no_show_all (); _route_prop_box->set_no_show_all (); _region_editor_box.set_no_show_all (); + _region_editor_box.set_spacing (4); _time_info_box->hide (); _route_prop_box->hide (); @@ -65,6 +68,7 @@ SelectionPropertiesBox::~SelectionPropertiesBox () delete _time_info_box; delete _route_prop_box; delete _region_editor; + delete _region_fx_box; } void @@ -114,9 +118,13 @@ SelectionPropertiesBox::delete_region_editor () if (!_region_editor) { return; } - _region_editor_box.remove (); + assert (_region_fx_box); + _region_editor_box.remove (*_region_editor); + _region_editor_box.remove (*_region_fx_box); delete _region_editor; + delete _region_fx_box; _region_editor = nullptr; + _region_fx_box = nullptr; _region_editor_box.hide (); } @@ -168,7 +176,10 @@ SelectionPropertiesBox::selection_changed () _region_editor->set_padding (4); _region_editor->set_edge_color (0x000000ff); // black _region_editor->show_all (); - _region_editor_box.add (*_region_editor); + _region_editor_box.pack_start (*_region_editor, false, false); + + _region_fx_box = new RegionFxPropertiesBox (rv->region ()); + _region_editor_box.pack_start (*_region_fx_box); rv->RegionViewGoingAway.connect_same_thread (_region_connection, std::bind (&SelectionPropertiesBox::delete_region_editor, this)); } _region_editor_box.show (); diff --git a/gtk2_ardour/selection_properties_box.h b/gtk2_ardour/selection_properties_box.h index 809977964a..d45d822950 100644 --- a/gtk2_ardour/selection_properties_box.h +++ b/gtk2_ardour/selection_properties_box.h @@ -27,14 +27,13 @@ #include "ardour/ardour.h" #include "ardour/session_handle.h" -#include "widgets/eventboxext.h" - namespace ARDOUR { class Session; } class TimeInfoBox; class RegionEditor; +class RegionFxPropertiesBox; class RoutePropertiesBox; class SelectionPropertiesBox : public Gtk::HBox, public ARDOUR::SessionHandlePtr @@ -51,10 +50,11 @@ private: void track_mouse_mode (); void delete_region_editor (); - TimeInfoBox* _time_info_box; - RoutePropertiesBox* _route_prop_box; - ArdourWidgets::EventBoxExt _region_editor_box; - RegionEditor* _region_editor; + TimeInfoBox* _time_info_box; + RoutePropertiesBox* _route_prop_box; + Gtk::HBox _region_editor_box; + RegionEditor* _region_editor; + RegionFxPropertiesBox* _region_fx_box; PBD::ScopedConnection _region_connection; PBD::ScopedConnection _editor_connection; diff --git a/gtk2_ardour/wscript b/gtk2_ardour/wscript index 004a8d85d7..0bbdde3ac6 100644 --- a/gtk2_ardour/wscript +++ b/gtk2_ardour/wscript @@ -248,6 +248,7 @@ gtk2_ardour_sources = [ 'region_editor.cc', 'region_editor_window.cc', 'region_fx_line.cc', + 'region_fx_properties_box.cc', 'region_gain_line.cc', 'region_layering_order_editor.cc', 'region_list_base.cc',