RefPtr<Action> ProcessorBox::delete_action;
RefPtr<Action> ProcessorBox::backspace_action;
RefPtr<Action> ProcessorBox::manage_pins_action;
+RefPtr<Action> ProcessorBox::disk_io_action;
RefPtr<Action> ProcessorBox::edit_action;
RefPtr<Action> ProcessorBox::edit_generic_action;
RefPtr<ActionGroup> ProcessorBox::processor_box_actions;
_processor->PropertyChanged.connect (name_connection, invalidator (*this), boost::bind (&ProcessorEntry::processor_property_changed, this, _1), gui_context());
_processor->ConfigurationChanged.connect (config_connection, invalidator (*this), boost::bind (&ProcessorEntry::processor_configuration_changed, this, _1, _2), gui_context());
+ const uint32_t limit_inline_controls = UIConfiguration::instance().get_max_inline_controls ();
+
set<Evoral::Parameter> p = _processor->what_can_be_automated ();
for (set<Evoral::Parameter>::iterator i = p.begin(); i != p.end(); ++i) {
std::string label = _processor->describe_parameter (*i);
+ if (label == X_("hidden")) {
+ continue;
+ }
+
if (boost::dynamic_pointer_cast<Send> (_processor)) {
label = _("Send");
} else if (boost::dynamic_pointer_cast<Return> (_processor)) {
/* Add non-Amp (Fader & Trim) controls to the processor box */
_vbox.pack_start (c->box);
}
+
+ if (limit_inline_controls > 0 && _controls.size() >= limit_inline_controls) {
+ break;
+ }
}
setup_tooltip ();
ProcessorEntry::build_controls_menu ()
{
using namespace Menu_Helpers;
+
+ if (!_plugin_display && _controls.empty ()) {
+ return NULL;
+ }
+
Menu* menu = manage (new Menu);
MenuList& items = menu->items ();
Gtk::CheckMenuItem* c = dynamic_cast<Gtk::CheckMenuItem*> (&items.back ());
c->set_active (_plugin_display->is_visible ());
c->signal_toggled().connect (sigc::mem_fun (*this, &ProcessorEntry::toggle_inline_display_visibility));
+ }
+
+ if (_controls.empty ()) {
+ return menu;
+ } else {
items.push_back (SeparatorElem ());
}
MenuElem (_("Hide All Controls"), sigc::mem_fun (*this, &ProcessorEntry::hide_all_controls))
);
- if (!_controls.empty ()) {
- items.push_back (SeparatorElem ());
- }
+ items.push_back (SeparatorElem ());
for (list<Control*>::iterator i = _controls.begin(); i != _controls.end(); ++i) {
items.push_back (CheckMenuElemNoMnemonic ((*i)->name ()));
if (!c) {
return;
}
- c->start_touch (c->session().transport_frame());
+ c->start_touch (c->session().transport_sample());
}
void
if (!c) {
return;
}
- c->stop_touch (c->session().transport_frame());
+ c->stop_touch (c->session().transport_sample());
}
void
: PluginDisplay (p, max_height)
, _entry (e)
, _scroll (false)
+ , _given_max_height (max_height)
{
std::string postfix = string_compose(_("\n%1+double-click to toggle inline-display"), Keyboard::tertiary_modifier_name ());
}
if (shm != _cur_height) {
- if (_scroll == sc || _cur_height < shm) {
- queue_resize ();
+ queue_resize ();
+ if (!_scroll && sc) {
+ _max_height = shm;
+ } else {
+ _max_height = _given_max_height;
}
_cur_height = shm;
}
+
_scroll = sc;
}
void
-ProcessorEntry::PluginInlineDisplay::display_frame (cairo_t* cr, double w, double h)
+ProcessorEntry::PluginInlineDisplay::display_sample (cairo_t* cr, double w, double h)
{
Gtkmm2ext::rounded_rectangle (cr, .5, -1.5, w - 1, h + 1, 7);
}
return 0;
}
- if (_route->is_monitor ()) {
+ if (_route->is_monitor () || _route->is_listenbus ()) {
+ return 0;
+ }
+
+ using namespace Menu_Helpers;
+ Menu* menu = manage (new Menu);
+ MenuList& items = menu->items();
+
+ for (RouteList::iterator r = rl->begin(); r != rl->end(); ++r) {
+ if ((*r)->is_master() || (*r)->is_monitor () || *r == _route) {
+ /* don't allow sending to master or monitor or to self */
+ continue;
+ }
+ if ((*r)->is_listenbus ()) {
+ continue;
+ }
+ if (_route->internal_send_for (*r)) {
+ /* aux-send to target already exists */
+ continue;
+ }
+ items.push_back (MenuElemNoMnemonic ((*r)->name(), sigc::bind (sigc::ptr_fun (ProcessorBox::rb_choose_aux), boost::weak_ptr<Route>(*r))));
+ }
+
+ return menu;
+}
+
+Gtk::Menu*
+ProcessorBox::build_possible_listener_menu ()
+{
+ boost::shared_ptr<RouteList> rl = _session->get_routes_with_internal_returns();
+
+ if (rl->empty()) {
+ /* No aux sends if there are no busses */
+ return 0;
+ }
+
+ if (_route->is_monitor () || _route->is_listenbus ()) {
return 0;
}
MenuList& items = menu->items();
for (RouteList::iterator r = rl->begin(); r != rl->end(); ++r) {
- if (!_route->internal_send_for (*r) && *r != _route) {
- items.push_back (MenuElemNoMnemonic ((*r)->name(), sigc::bind (sigc::ptr_fun (ProcessorBox::rb_choose_aux), boost::weak_ptr<Route>(*r))));
+ if ((*r)->is_master() || (*r)->is_monitor () || *r == _route) {
+ /* don't allow sending to master or monitor or to self */
+ continue;
}
+ if (!(*r)->is_listenbus ()) {
+ continue;
+ }
+ if (_route->internal_send_for (*r)) {
+ /* aux-send to target already exists */
+ continue;
+ }
+ items.push_back (MenuElemNoMnemonic ((*r)->name(), sigc::bind (sigc::ptr_fun (ProcessorBox::rb_choose_aux), boost::weak_ptr<Route>(*r))));
+ }
+
+ return menu;
+}
+
+Gtk::Menu*
+ProcessorBox::build_possible_remove_listener_menu ()
+{
+ boost::shared_ptr<RouteList> rl = _session->get_routes_with_internal_returns();
+
+ if (rl->empty()) {
+ /* No aux sends if there are no busses */
+ return 0;
+ }
+
+ if (_route->is_monitor () || _route->is_listenbus ()) {
+ return 0;
+ }
+
+ using namespace Menu_Helpers;
+ Menu* menu = manage (new Menu);
+ MenuList& items = menu->items();
+
+ for (RouteList::iterator r = rl->begin(); r != rl->end(); ++r) {
+ if ((*r)->is_master() || (*r)->is_monitor () || *r == _route) {
+ /* don't allow sending to master or monitor or to self */
+ continue;
+ }
+ if (!(*r)->is_listenbus ()) {
+ continue;
+ }
+ if (!_route->internal_send_for (*r)) {
+ /* aux-send to target already exists */
+ continue;
+ }
+ items.push_back (MenuElemNoMnemonic ((*r)->name(), sigc::bind (sigc::ptr_fun (ProcessorBox::rb_remove_aux), boost::weak_ptr<Route>(*r))));
}
return menu;
}
}
- ActionManager::get_action (X_("ProcessorMenu"), "newinsert")->set_sensitive (!_route->is_monitor ());
- ActionManager::get_action (X_("ProcessorMenu"), "newsend")->set_sensitive (!_route->is_monitor ());
+ Gtk::MenuItem* listen_menu_item = dynamic_cast<Gtk::MenuItem*>(ActionManager::get_widget("/ProcessorMenu/newlisten"));
+
+ if (listen_menu_item) {
+ Menu* m = build_possible_listener_menu();
+ if (m && !m->items().empty()) {
+ listen_menu_item->set_submenu (*m);
+ listen_menu_item->set_sensitive (true);
+ } else {
+ /* stupid gtkmm: we need to pass a null reference here */
+ gtk_menu_item_set_submenu (listen_menu_item->gobj(), 0);
+ listen_menu_item->set_sensitive (false);
+ }
+ }
+
+ Gtk::MenuItem* remove_listen_menu_item = dynamic_cast<Gtk::MenuItem*>(ActionManager::get_widget("/ProcessorMenu/removelisten"));
+
+ if (remove_listen_menu_item) {
+ Menu* m = build_possible_remove_listener_menu();
+ if (m && !m->items().empty()) {
+ remove_listen_menu_item->set_submenu (*m);
+ remove_listen_menu_item->set_sensitive (true);
+ } else {
+ /* stupid gtkmm: we need to pass a null reference here */
+ gtk_menu_item_set_submenu (remove_listen_menu_item->gobj(), 0);
+ remove_listen_menu_item->set_sensitive (false);
+ }
+ }
+
+ ActionManager::get_action (X_("ProcessorMenu"), "newinsert")->set_sensitive (!_route->is_monitor () && !_route->is_listenbus ());
+ ActionManager::get_action (X_("ProcessorMenu"), "newsend")->set_sensitive (!_route->is_monitor () && !_route->is_listenbus ());
ProcessorEntry* single_selection = 0;
if (processor_display.selection().size() == 1) {
/* Sensitise actions as approprioate */
-
const bool sensitive = !processor_display.selection().empty() && ! stub_processor_selected ();
paste_action->set_sensitive (!_p_selection.processors.empty());
}
manage_pins_action->set_sensitive (pi != 0);
+ if (boost::dynamic_pointer_cast<Track>(_route)) {
+ disk_io_action->set_sensitive (true);
+ } else {
+ disk_io_action->set_sensitive (false);
+ }
/* allow editing with an Ardour-generated UI for plugin inserts with editors */
edit_action->set_sensitive (pi && pi->plugin()->has_editor ());
return true;
// XXX SHAREDPTR delete plugin here .. do we even need to care?
} else if (plugins.size() == 1 && UIConfiguration::instance().get_open_gui_after_adding_plugin()) {
- if (boost::dynamic_pointer_cast<PluginInsert>(processor)->plugin()->has_inline_display() && UIConfiguration::instance().get_prefer_inline_over_gui()) {
- ;
- } else if (_session->engine().connected () && processor_can_be_edited (processor)) {
+ if (processor->what_can_be_automated ().size () == 0) {
+ ; /* plugin without controls, don't show ui */
+ }
+ else if (boost::dynamic_pointer_cast<PluginInsert>(processor)->plugin()->has_inline_display() && UIConfiguration::instance().get_prefer_inline_over_gui()) {
+ ; /* only show inline display */
+ }
+ else if (_session->engine().connected () && processor_can_be_edited (processor)) {
if ((*p)->has_editor ()) {
edit_processor (processor);
} else if (boost::dynamic_pointer_cast<PluginInsert>(processor)->plugin()->parameter_count() > 0) {
return;
}
- _session->add_internal_send (target, _placement, _route);
+ if (target->is_listenbus ()) {
+ _route->add_personal_send (target);
+ } else {
+ _session->add_internal_send (target, _placement, _route);
+ }
+}
+
+void
+ProcessorBox::remove_aux (boost::weak_ptr<Route> wr)
+{
+ if (!_route) {
+ return;
+ }
+
+ boost::shared_ptr<Route> target = wr.lock();
+
+ if (!target) {
+ return;
+ }
+ boost::shared_ptr<Send> send = _route->internal_send_for (target);
+ boost::shared_ptr<Processor> proc = boost::dynamic_pointer_cast<Processor> (send);
+ _route->remove_processor (proc);
+
}
void
return;
}
- /* not on the list; add it */
+ /* see also ProcessorBox::get_editor_window */
+ bool have_ui = false;
- string loc;
-#if 0 // is this still needed? Why?
- if (_parent_strip) {
- if (_parent_strip->mixer_owned()) {
- loc = X_("M");
- } else {
- loc = X_("R");
+ if (boost::dynamic_pointer_cast<PluginInsert> (p)) {
+ have_ui = true;
+ }
+ else if (boost::dynamic_pointer_cast<PortInsert> (p)) {
+ have_ui = true;
+ }
+ else if (boost::dynamic_pointer_cast<Send> (p)) {
+ if (!boost::dynamic_pointer_cast<InternalSend> (p)) {
+ have_ui = true;
+ }
+ }
+ else if (boost::dynamic_pointer_cast<Return> (p)) {
+ if (!boost::dynamic_pointer_cast<InternalReturn> (p)) {
+ have_ui = true;
}
- } else {
- loc = X_("P");
}
-#else
- loc = X_("P");
-#endif
+
+ if (!have_ui) {
+ return;
+ }
ProcessorWindowProxy* wp = new ProcessorWindowProxy (
- string_compose ("%1-%2-%3", loc, _route->id(), p->id()),
- this,
- w);
+ string_compose ("P-%1-%2", _route->id(), p->id()),
+ this,
+ w);
const XMLNode* ui_xml = _session->extra_xml (X_("UI"));
if (!p || p->pinmgr_proxy ()) {
return;
}
+ if (!boost::dynamic_pointer_cast<PluginInsert> (p)) {
+ return;
+ }
PluginPinWindowProxy* wp = new PluginPinWindowProxy (
- string_compose ("PM-%2-%3", _route->id(), p->id()), w);
+ string_compose ("PM-%1-%2", _route->id(), p->id()), w);
wp->set_session (_session);
const XMLNode* ui_xml = _session->extra_xml (X_("UI"));
ab_direction = !ab_direction;
}
+void
+ProcessorBox::set_disk_io_position (DiskIOPoint diop)
+{
+ boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track> (_route);
+ if (t) {
+ t->set_disk_io_point (diop);
+ }
+}
void
ProcessorBox::clear_processors ()
ActionManager::engine_sensitive_actions.push_back (act);
myactions.register_action (processor_box_actions, X_("newaux"), _("New Aux Send ..."));
+ myactions.register_action (processor_box_actions, X_("newlisten"), _("New Monitor Send ..."));
+ myactions.register_action (processor_box_actions, X_("removelisten"), _("Remove Monitor Send ..."));
myactions.register_action (processor_box_actions, X_("controls"), _("Controls"));
myactions.register_action (processor_box_actions, X_("send_options"), _("Send Options"));
processor_box_actions, X_("manage-pins"), _("Pin Connections..."),
sigc::ptr_fun (ProcessorBox::rb_manage_pins));
+ /* Disk IO stuff */
+ disk_io_action = myactions.register_action (processor_box_actions, X_("disk-io-menu"), _("Disk I/O ..."));
+ myactions.register_action (processor_box_actions, X_("disk-io-prefader"), _("Pre-Fader."), sigc::bind (sigc::ptr_fun (ProcessorBox::rb_set_disk_io_position), DiskIOPreFader));
+ myactions.register_action (processor_box_actions, X_("disk-io-postfader"), _("Post-Fader."), sigc::bind (sigc::ptr_fun (ProcessorBox::rb_set_disk_io_position), DiskIOPostFader));
+ myactions.register_action (processor_box_actions, X_("disk-io-custom"), _("Custom."), sigc::bind (sigc::ptr_fun (ProcessorBox::rb_set_disk_io_position), DiskIOCustom));
+
/* show editors */
edit_action = myactions.register_action (
processor_box_actions, X_("edit"), _("Edit..."),
_current_processor_box->ab_plugins ();
}
+void
+ProcessorBox::rb_set_disk_io_position (DiskIOPoint diop)
+{
+ if (_current_processor_box == 0) {
+ return;
+ }
+
+ _current_processor_box->set_disk_io_position (diop);
+}
+
void
ProcessorBox::rb_manage_pins ()
{
_current_processor_box->choose_aux (wr);
}
+void
+ProcessorBox::rb_remove_aux (boost::weak_ptr<Route> wr)
+{
+ if (_current_processor_box == 0) {
+ return;
+ }
+
+ _current_processor_box->remove_aux (wr);
+}
+
void
ProcessorBox::rb_clear ()
{