Add 'controls' item to plugin insert context menu to always show Ardour generated controls for plugin, even if the plugin has a GUI. In particular, this gives you UI access to presets and the other handy stuff ardour sticks at the top, for inherently broken external UIs which don't allow Ardour to add such things.
Fix crash related to scale points when showing plugin UIs. Fix packing of scrolled generic plugin UI so the controls expand (rather than leaving a ton of wasted empty space and using unnecessary scroll bars). git-svn-id: svn://localhost/ardour2/branches/3.0@9551 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
424b3479de
commit
041c882143
|
@ -537,6 +537,7 @@
|
|||
<menuitem action='ab_plugins'/>
|
||||
<separator/>
|
||||
<menuitem action='edit'/>
|
||||
<menuitem action='controls'/>
|
||||
</popup>
|
||||
|
||||
<popup name='ShuttleUnitPopup'>
|
||||
|
|
|
@ -74,7 +74,7 @@ GenericPluginUI::GenericPluginUI (boost::shared_ptr<PluginInsert> pi, bool scrol
|
|||
set_border_width (10);
|
||||
//set_homogeneous (false);
|
||||
|
||||
pack_start (main_contents, false, false);
|
||||
pack_start (main_contents, true, true);
|
||||
settings_box.set_homogeneous (false);
|
||||
|
||||
HBox* constraint_hbox = manage (new HBox);
|
||||
|
@ -99,7 +99,7 @@ GenericPluginUI::GenericPluginUI (boost::shared_ptr<PluginInsert> pi, bool scrol
|
|||
|
||||
VBox* v1_box = manage (new VBox);
|
||||
VBox* v2_box = manage (new VBox);
|
||||
pack_end (plugin_analysis_expander, true, true);
|
||||
pack_end (plugin_analysis_expander, false, false);
|
||||
|
||||
v1_box->pack_start (*smaller_hbox, false, true);
|
||||
v2_box->pack_start (focus_button, false, true);
|
||||
|
@ -111,7 +111,7 @@ GenericPluginUI::GenericPluginUI (boost::shared_ptr<PluginInsert> pi, bool scrol
|
|||
|
||||
main_contents.pack_start (*constraint_hbox, false, false);
|
||||
|
||||
if ( is_scrollable ) {
|
||||
if (is_scrollable ) {
|
||||
scroller.set_policy (Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
|
||||
scroller.set_name ("PluginEditor");
|
||||
scroller_view.set_name("PluginEditor");
|
||||
|
@ -120,8 +120,7 @@ GenericPluginUI::GenericPluginUI (boost::shared_ptr<PluginInsert> pi, bool scrol
|
|||
|
||||
main_contents.pack_start (scroller, true, true);
|
||||
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
main_contents.pack_start (hpacker, false, false);
|
||||
}
|
||||
|
||||
|
@ -216,7 +215,7 @@ GenericPluginUI::build ()
|
|||
box->set_spacing (1);
|
||||
|
||||
frame->add (*box);
|
||||
hpacker.pack_start(*frame,true,true);
|
||||
hpacker.pack_start(*frame, true, true);
|
||||
|
||||
x = 1;
|
||||
}
|
||||
|
@ -650,7 +649,7 @@ GenericPluginUI::update_control_display (ControlUI* cui)
|
|||
|
||||
cui->ignore_change++;
|
||||
|
||||
if (cui->combo) {
|
||||
if (cui->combo && cui->combo_map) {
|
||||
std::map<string,float>::iterator it;
|
||||
for (it = cui->combo_map->begin(); it != cui->combo_map->end(); ++it) {
|
||||
if (it->second == val) {
|
||||
|
@ -694,7 +693,7 @@ GenericPluginUI::control_port_toggled (ControlUI* cui)
|
|||
void
|
||||
GenericPluginUI::control_combo_changed (ControlUI* cui)
|
||||
{
|
||||
if (!cui->ignore_change) {
|
||||
if (!cui->ignore_change && cui->combo_map) {
|
||||
string value = cui->combo->get_active_text();
|
||||
std::map<string,float> mapping = *cui->combo_map;
|
||||
insert->automation_control(cui->parameter())->set_value(mapping[value]);
|
||||
|
|
|
@ -77,17 +77,23 @@ using namespace PBD;
|
|||
using namespace Gtkmm2ext;
|
||||
using namespace Gtk;
|
||||
|
||||
PluginUIWindow::PluginUIWindow (Gtk::Window* win, boost::shared_ptr<PluginInsert> insert, bool scrollable)
|
||||
PluginUIWindow::PluginUIWindow (
|
||||
Gtk::Window* win,
|
||||
boost::shared_ptr<PluginInsert> insert,
|
||||
bool scrollable,
|
||||
bool editor)
|
||||
: parent (win)
|
||||
, was_visible (false)
|
||||
, _keyboard_focused (false)
|
||||
, was_visible (false)
|
||||
, _keyboard_focused (false)
|
||||
{
|
||||
bool have_gui = false;
|
||||
|
||||
Label* label = manage (new Label());
|
||||
label->set_markup ("<b>THIS IS THE PLUGIN UI</b>");
|
||||
|
||||
if (insert->plugin()->has_editor()) {
|
||||
std::cout << "SHOW UI " << insert->plugin()->unique_id()
|
||||
<< " editor: " << editor << std::endl;
|
||||
if (editor && insert->plugin()->has_editor()) {
|
||||
switch (insert->type()) {
|
||||
case ARDOUR::VST:
|
||||
have_gui = create_vst_editor (insert);
|
||||
|
@ -119,8 +125,7 @@ PluginUIWindow::PluginUIWindow (Gtk::Window* win, boost::shared_ptr<PluginInsert
|
|||
}
|
||||
|
||||
if (!have_gui) {
|
||||
|
||||
GenericPluginUI* pu = new GenericPluginUI (insert, scrollable);
|
||||
GenericPluginUI* pu = new GenericPluginUI (insert, scrollable);
|
||||
|
||||
_pluginui = pu;
|
||||
_pluginui->KeyboardFocused.connect (sigc::mem_fun (*this, &PluginUIWindow::keyboard_focused));
|
||||
|
@ -281,7 +286,7 @@ PluginUIWindow::create_audiounit_editor (boost::shared_ptr<PluginInsert>)
|
|||
#else
|
||||
VBox* box;
|
||||
_pluginui = create_au_gui (insert, &box);
|
||||
_pluginui->KeyboardFocused.connect (sigc::mem_fun (*this, &PluginUIWindow::keyboard_focused));
|
||||
_pluginui->KeyboardFocused.connect (sigc::mem_fun (*this, &PluginUIWindow::keyboard_focused));
|
||||
add (*box);
|
||||
|
||||
Application::instance()->ActivationChanged.connect (mem_fun (*this, &PluginUIWindow::app_activated));
|
||||
|
@ -347,32 +352,32 @@ PluginUIWindow::on_key_press_event (GdkEventKey* event)
|
|||
{
|
||||
if (_keyboard_focused) {
|
||||
if (_pluginui) {
|
||||
if (_pluginui->non_gtk_gui()) {
|
||||
_pluginui->forward_key_event (event);
|
||||
} else {
|
||||
return relay_key_press (event, this);
|
||||
}
|
||||
if (_pluginui->non_gtk_gui()) {
|
||||
_pluginui->forward_key_event (event);
|
||||
} else {
|
||||
return relay_key_press (event, this);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
/* for us to be getting key press events, there really
|
||||
MUST be a _pluginui, but just to be safe, check ...
|
||||
*/
|
||||
/* for us to be getting key press events, there really
|
||||
MUST be a _pluginui, but just to be safe, check ...
|
||||
*/
|
||||
|
||||
if (_pluginui) {
|
||||
if (_pluginui->non_gtk_gui()) {
|
||||
/* pass editor window as the window for the event
|
||||
to be handled in, not this one, because there are
|
||||
no widgets in this window that we want to have
|
||||
key focus.
|
||||
*/
|
||||
return relay_key_press (event, &PublicEditor::instance());
|
||||
} else {
|
||||
return relay_key_press (event, this);
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
if (_pluginui) {
|
||||
if (_pluginui->non_gtk_gui()) {
|
||||
/* pass editor window as the window for the event
|
||||
to be handled in, not this one, because there are
|
||||
no widgets in this window that we want to have
|
||||
key focus.
|
||||
*/
|
||||
return relay_key_press (event, &PublicEditor::instance());
|
||||
} else {
|
||||
return relay_key_press (event, this);
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -381,10 +386,10 @@ PluginUIWindow::on_key_release_event (GdkEventKey *event)
|
|||
{
|
||||
if (_keyboard_focused) {
|
||||
if (_pluginui) {
|
||||
if (_pluginui->non_gtk_gui()) {
|
||||
_pluginui->forward_key_event (event);
|
||||
}
|
||||
return true;
|
||||
if (_pluginui->non_gtk_gui()) {
|
||||
_pluginui->forward_key_event (event);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
|
|
|
@ -211,7 +211,7 @@ class GenericPluginUI : public PlugUIBase, public Gtk::VBox
|
|||
|
||||
/* input */
|
||||
|
||||
Gtk::ComboBoxText* combo;
|
||||
Gtk::ComboBoxText* combo;
|
||||
std::map<std::string, float>* combo_map;
|
||||
Gtk::ToggleButton* button;
|
||||
boost::shared_ptr<AutomationController> controller;
|
||||
|
@ -261,7 +261,10 @@ class GenericPluginUI : public PlugUIBase, public Gtk::VBox
|
|||
class PluginUIWindow : public Gtk::Window
|
||||
{
|
||||
public:
|
||||
PluginUIWindow (Gtk::Window*, boost::shared_ptr<ARDOUR::PluginInsert> insert, bool scrollable=false);
|
||||
PluginUIWindow (Gtk::Window*,
|
||||
boost::shared_ptr<ARDOUR::PluginInsert> insert,
|
||||
bool scrollable=false,
|
||||
bool editor=true);
|
||||
~PluginUIWindow ();
|
||||
|
||||
PlugUIBase& pluginui() { return *_pluginui; }
|
||||
|
|
|
@ -92,6 +92,7 @@ RefPtr<Action> ProcessorBox::paste_action;
|
|||
RefPtr<Action> ProcessorBox::cut_action;
|
||||
RefPtr<Action> ProcessorBox::rename_action;
|
||||
RefPtr<Action> ProcessorBox::edit_action;
|
||||
RefPtr<Action> ProcessorBox::controls_action;
|
||||
Glib::RefPtr<Gdk::Pixbuf> SendProcessorEntry::_slider;
|
||||
|
||||
ProcessorEntry::ProcessorEntry (boost::shared_ptr<Processor> p, Width w)
|
||||
|
@ -883,14 +884,24 @@ ProcessorBox::build_processor_menu ()
|
|||
void
|
||||
ProcessorBox::selection_changed ()
|
||||
{
|
||||
bool const sensitive = (processor_display.selection().empty()) ? false : true;
|
||||
ActionManager::set_sensitive (ActionManager::plugin_selection_sensitive_actions, sensitive);
|
||||
edit_action->set_sensitive (one_processor_can_be_edited ());
|
||||
const bool sensitive = !processor_display.selection().empty();
|
||||
ActionManager::set_sensitive(ActionManager::plugin_selection_sensitive_actions,
|
||||
sensitive);
|
||||
edit_action->set_sensitive(one_processor_can_be_edited());
|
||||
|
||||
const bool single_selection = (processor_display.selection().size() == 1);
|
||||
|
||||
boost::shared_ptr<PluginInsert> pi;
|
||||
if (single_selection) {
|
||||
pi = boost::dynamic_pointer_cast<PluginInsert>(
|
||||
processor_display.selection().front()->processor());
|
||||
}
|
||||
|
||||
/* enable gui for plugin inserts with editors */
|
||||
controls_action->set_sensitive(pi && pi->plugin()->has_editor());
|
||||
|
||||
/* disallow rename for multiple selections and for plugin inserts */
|
||||
rename_action->set_sensitive (
|
||||
processor_display.selection().size() == 1 && boost::dynamic_pointer_cast<PluginInsert> (processor_display.selection().front()->processor()) == 0
|
||||
);
|
||||
rename_action->set_sensitive(single_selection && pi);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1838,10 +1849,10 @@ ProcessorBox::toggle_edit_processor (boost::shared_ptr<Processor> processor)
|
|||
|
||||
} else if ((retrn = boost::dynamic_pointer_cast<Return> (processor)) != 0) {
|
||||
|
||||
if (boost::dynamic_pointer_cast<InternalReturn> (retrn)) {
|
||||
/* no GUI for these */
|
||||
return;
|
||||
}
|
||||
if (boost::dynamic_pointer_cast<InternalReturn> (retrn)) {
|
||||
/* no GUI for these */
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_session->engine().connected()) {
|
||||
return;
|
||||
|
@ -1921,6 +1932,28 @@ ProcessorBox::toggle_edit_processor (boost::shared_ptr<Processor> processor)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
ProcessorBox::toggle_processor_controls (boost::shared_ptr<Processor> processor)
|
||||
{
|
||||
boost::shared_ptr<PluginInsert> plugin_insert
|
||||
= boost::dynamic_pointer_cast<PluginInsert>(processor);
|
||||
if (!plugin_insert) {
|
||||
return;
|
||||
}
|
||||
|
||||
Container* toplevel = get_toplevel();
|
||||
Window* win = dynamic_cast<Gtk::Window*>(toplevel);
|
||||
PluginUIWindow* plugin_ui = new PluginUIWindow(win, plugin_insert, true, false);
|
||||
plugin_ui->set_title(generate_processor_title (plugin_insert));
|
||||
|
||||
if (plugin_ui->is_visible()) {
|
||||
plugin_ui->hide();
|
||||
} else {
|
||||
plugin_ui->show_all();
|
||||
plugin_ui->present();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ProcessorBox::register_actions ()
|
||||
{
|
||||
|
@ -1971,15 +2004,21 @@ ProcessorBox::register_actions ()
|
|||
/* activation etc. */
|
||||
|
||||
ActionManager::register_action (popup_act_grp, X_("activate_all"), _("Activate all"),
|
||||
sigc::ptr_fun (ProcessorBox::rb_activate_all));
|
||||
sigc::ptr_fun (ProcessorBox::rb_activate_all));
|
||||
ActionManager::register_action (popup_act_grp, X_("deactivate_all"), _("Deactivate all"),
|
||||
sigc::ptr_fun (ProcessorBox::rb_deactivate_all));
|
||||
sigc::ptr_fun (ProcessorBox::rb_deactivate_all));
|
||||
ActionManager::register_action (popup_act_grp, X_("ab_plugins"), _("A/B Plugins"),
|
||||
sigc::ptr_fun (ProcessorBox::rb_ab_plugins));
|
||||
sigc::ptr_fun (ProcessorBox::rb_ab_plugins));
|
||||
|
||||
/* show editors */
|
||||
edit_action = ActionManager::register_action (popup_act_grp, X_("edit"), _("Edit..."),
|
||||
sigc::ptr_fun (ProcessorBox::rb_edit));
|
||||
edit_action = ActionManager::register_action (
|
||||
popup_act_grp, X_("edit"), _("Edit..."),
|
||||
sigc::ptr_fun (ProcessorBox::rb_edit));
|
||||
|
||||
/* show plugin GUI */
|
||||
controls_action = ActionManager::register_action (
|
||||
popup_act_grp, X_("controls"), _("Controls..."),
|
||||
sigc::ptr_fun (ProcessorBox::rb_controls));
|
||||
|
||||
ActionManager::add_action_group (popup_act_grp);
|
||||
}
|
||||
|
@ -2160,6 +2199,16 @@ ProcessorBox::rb_edit ()
|
|||
_current_processor_box->for_selected_processors (&ProcessorBox::toggle_edit_processor);
|
||||
}
|
||||
|
||||
void
|
||||
ProcessorBox::rb_controls ()
|
||||
{
|
||||
if (_current_processor_box == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
_current_processor_box->for_selected_processors (&ProcessorBox::toggle_processor_controls);
|
||||
}
|
||||
|
||||
void
|
||||
ProcessorBox::route_property_changed (const PropertyChange& what_changed)
|
||||
{
|
||||
|
@ -2255,9 +2304,9 @@ void
|
|||
ProcessorBox::set_processor_ui (boost::shared_ptr<Processor> p, Gtk::Window* w)
|
||||
{
|
||||
list<ProcessorWindowProxy*>::iterator i = _processor_window_proxies.begin ();
|
||||
|
||||
p->set_ui (w);
|
||||
|
||||
|
||||
p->set_ui (w);
|
||||
|
||||
while (i != _processor_window_proxies.end()) {
|
||||
boost::shared_ptr<Processor> t = (*i)->processor().lock ();
|
||||
if (t && t == p) {
|
||||
|
|
|
@ -215,6 +215,7 @@ class ProcessorBox : public Gtk::HBox, public PluginInterestedObject, public ARD
|
|||
|
||||
Gtk::Window* get_processor_ui (boost::shared_ptr<ARDOUR::Processor>) const;
|
||||
void toggle_edit_processor (boost::shared_ptr<ARDOUR::Processor>);
|
||||
void toggle_processor_controls (boost::shared_ptr<ARDOUR::Processor>);
|
||||
|
||||
sigc::signal<void,boost::shared_ptr<ARDOUR::Processor> > ProcessorSelected;
|
||||
sigc::signal<void,boost::shared_ptr<ARDOUR::Processor> > ProcessorUnselected;
|
||||
|
@ -313,12 +314,13 @@ class ProcessorBox : public Gtk::HBox, public PluginInterestedObject, public ARD
|
|||
void for_selected_processors (void (ProcessorBox::*pmf)(boost::shared_ptr<ARDOUR::Processor>));
|
||||
void get_selected_processors (ProcSelection&) const;
|
||||
|
||||
bool can_cut() const;
|
||||
bool can_cut() const;
|
||||
|
||||
static Glib::RefPtr<Gtk::Action> cut_action;
|
||||
static Glib::RefPtr<Gtk::Action> paste_action;
|
||||
static Glib::RefPtr<Gtk::Action> rename_action;
|
||||
static Glib::RefPtr<Gtk::Action> edit_action;
|
||||
static Glib::RefPtr<Gtk::Action> controls_action;
|
||||
void paste_processor_state (const XMLNodeList&, boost::shared_ptr<ARDOUR::Processor>);
|
||||
|
||||
void activate_processor (boost::shared_ptr<ARDOUR::Processor>);
|
||||
|
@ -353,6 +355,7 @@ class ProcessorBox : public Gtk::HBox, public PluginInterestedObject, public ARD
|
|||
static void rb_deactivate_all ();
|
||||
static void rb_ab_plugins ();
|
||||
static void rb_edit ();
|
||||
static void rb_controls ();
|
||||
|
||||
void route_property_changed (const PBD::PropertyChange&);
|
||||
std::string generate_processor_title (boost::shared_ptr<ARDOUR::PluginInsert> pi);
|
||||
|
|
|
@ -57,7 +57,7 @@ class PluginInsert : public Processor
|
|||
|
||||
void activate ();
|
||||
void deactivate ();
|
||||
void flush ();
|
||||
void flush ();
|
||||
|
||||
int set_block_size (pframes_t nframes);
|
||||
|
||||
|
@ -83,13 +83,13 @@ class PluginInsert : public Processor
|
|||
|
||||
void set_value (double val);
|
||||
double get_value (void) const;
|
||||
XMLNode& get_state();
|
||||
XMLNode& get_state();
|
||||
|
||||
double user_to_ui (double) const;
|
||||
double ui_to_user (double) const;
|
||||
double plugin_to_ui (double) const;
|
||||
double plugin_to_user (double) const;
|
||||
|
||||
|
||||
private:
|
||||
double user_to_plugin (double) const;
|
||||
|
||||
|
@ -158,7 +158,7 @@ class PluginInsert : public Processor
|
|||
void set_automatable ();
|
||||
void control_list_automation_state_changed (Evoral::Parameter, AutoState);
|
||||
void set_parameter_state_2X (const XMLNode& node, int version);
|
||||
void set_control_ids (const XMLNode&, int version);
|
||||
void set_control_ids (const XMLNode&, int version);
|
||||
|
||||
int32_t count_for_configuration (ChanCount in, ChanCount out) const;
|
||||
|
||||
|
|
Loading…
Reference in New Issue