#include <sigc++/bind.h>
-#include "pbd/convert.h"
#include "canvas/utils.h"
#include <glibmm/miscutils.h>
#include "plugin_ui.h"
#include "port_insert_ui.h"
#include "processor_box.h"
+#include "processor_selection.h"
#include "public_editor.h"
#include "return_ui.h"
-#include "route_processor_selection.h"
#include "script_selector.h"
#include "send_ui.h"
#include "timers.h"
#include "tooltips.h"
#include "new_plugin_preset_dialog.h"
-#include "i18n.h"
+#include "pbd/i18n.h"
#ifdef AUDIOUNIT_SUPPORT
class AUPluginUI;
boost::shared_ptr<PluginInsert> pi = boost::dynamic_pointer_cast<PluginInsert> (_processor);
if (pi && pi->plugin() && pi->plugin()->has_inline_display()) {
if (pi->plugin()->get_info()->type != ARDOUR::Lua) {
- _plugin_display = new PluginDisplay (pi->plugin(),
+ _plugin_display = new PluginDisplay (*this, pi->plugin(),
std::max (60.f, rintf(112.f * UIConfiguration::instance().get_ui_scale())));
} else {
assert (boost::dynamic_pointer_cast<LuaProc>(pi->plugin()));
- _plugin_display = new LuaPluginDisplay (boost::dynamic_pointer_cast<LuaProc>(pi->plugin()),
+ _plugin_display = new LuaPluginDisplay (*this, boost::dynamic_pointer_cast<LuaProc>(pi->plugin()),
std::max (60.f, rintf(112.f * UIConfiguration::instance().get_ui_scale())));
}
_vbox.pack_start (*_plugin_display);
_vbox.pack_end (output_routing_icon);
_vbox.pack_end (output_icon);
- _button.set_active (_processor->active());
+ _button.set_active (_processor->enabled ());
input_icon.set_no_show_all(true);
routing_icon.set_no_show_all(true);
}
}
+ boost::shared_ptr<InternalSend> aux;
+ if ((aux = boost::dynamic_pointer_cast<InternalSend> (_processor))) {
+ if (aux->allow_feedback ()) {
+ _button.set_name ("processor auxfeedback");
+ return;
+ }
+ }
+
switch (_position) {
case PreFader:
if (_plugin_display) { _plugin_display->set_name ("processor prefader"); }
_parent->all_visible_processors_active(false);
if (_position == Fader) {
- _processor->deactivate ();
+ _processor->enable (false);
}
}
else {
- _processor->deactivate ();
+ _processor->enable (false);
}
} else {
_parent->all_visible_processors_active(true);
if (_position == Fader) {
- _processor->activate ();
+ _processor->enable (true);
}
}
else {
- _processor->activate ();
+ _processor->enable (true);
}
}
}
ProcessorEntry::processor_active_changed ()
{
if (_processor) {
- _button.set_active (_processor->active());
+ _button.set_active (_processor->enabled ());
}
}
if (pi) {
std::string postfix = "";
uint32_t replicated;
+
+ if (pi->plugin()->has_inline_display()) {
+ postfix += string_compose(_("\n%1+double-click to toggle inline-display"), Keyboard::tertiary_modifier_name ());
+ }
+
if ((replicated = pi->get_count()) > 1) {
- postfix = string_compose(_("\nThis mono plugin has been replicated %1 times."), replicated);
+ postfix += string_compose(_("\nThis mono plugin has been replicated %1 times."), replicated);
}
+
if (pi->plugin()->has_editor()) {
ARDOUR_UI_UTILS::set_tooltip (_button,
- string_compose (_("<b>%1</b>\nDouble-click to show GUI.\n%2+double-click to show generic GUI.%3"), name (Wide), Keyboard::primary_modifier_name (), postfix));
+ string_compose (_("<b>%1</b>\nDouble-click to show GUI.\n%2+double-click to show generic GUI.%3"), name (Wide), Keyboard::secondary_modifier_name (), postfix));
} else {
ARDOUR_UI_UTILS::set_tooltip (_button,
string_compose (_("<b>%1</b>\nDouble-click to show generic GUI.%2"), name (Wide), postfix));
if (_plugin_display) {
XMLNode* c = new XMLNode (X_("Object"));
- c->add_property (X_("id"), X_("InlineDisplay"));
- c->add_property (X_("visible"), _plugin_display->is_visible ());
+ c->set_property (X_("id"), X_("InlineDisplay"));
+ c->set_property (X_("visible"), _plugin_display->is_visible ());
node->add_child_nocopy (*c);
}
}
if (_plugin_display) {
XMLNode* n = GUIObjectState::get_node (node, X_("InlineDisplay"));
- XMLProperty const * p = n ? n->property (X_("visible")) : NULL;
- if (p) {
- if (string_is_affirmative (p->value ())) {
- _plugin_display->show();
+ if (!n) return;
+
+ bool visible;
+ if (n->get_property (X_("visible"), visible)) {
+ if (visible) {
+ _plugin_display->show ();
} else {
- _plugin_display->hide();
+ _plugin_display->hide ();
}
}
}
Menu* menu = manage (new Menu);
MenuList& items = menu->items ();
- boost::shared_ptr<Send> send = boost::dynamic_pointer_cast<Send> (_processor);
- if (send) {
+ if (!ARDOUR::Profile->get_mixbus()) {
+ boost::shared_ptr<Send> send = boost::dynamic_pointer_cast<Send> (_processor);
+ if (send) {
+ items.push_back (CheckMenuElem (_("Link panner controls")));
+ Gtk::CheckMenuItem* c = dynamic_cast<Gtk::CheckMenuItem*> (&items.back ());
+ c->set_active (send->panner_shell()->is_linked_to_route());
+ c->signal_toggled().connect (sigc::mem_fun (*this, &ProcessorEntry::toggle_panner_link));
+ }
+ }
- items.push_back (CheckMenuElem (_("Link panner controls")));
+ boost::shared_ptr<InternalSend> aux = boost::dynamic_pointer_cast<InternalSend> (_processor);
+ if (aux) {
+ items.push_back (CheckMenuElem (_("Allow Feedback Loop")));
Gtk::CheckMenuItem* c = dynamic_cast<Gtk::CheckMenuItem*> (&items.back ());
- c->set_active (send->panner_shell()->is_linked_to_route());
- c->signal_toggled().connect (sigc::mem_fun (*this, &ProcessorEntry::toggle_panner_link));
-
+ c->set_active (aux->allow_feedback());
+ c->signal_toggled().connect (sigc::mem_fun (*this, &ProcessorEntry::toggle_allow_feedback));
}
return menu;
}
}
}
+void
+ProcessorEntry::toggle_allow_feedback ()
+{
+ boost::shared_ptr<InternalSend> aux = boost::dynamic_pointer_cast<InternalSend> (_processor);
+ if (aux) {
+ aux->set_allow_feedback (!aux->allow_feedback ());
+ }
+}
+
ProcessorEntry::Control::Control (boost::shared_ptr<AutomationControl> c, string const & n)
: _control (c)
, _adjustment (gain_to_slider_position_with_max (1.0, Config->get_max_gain()), 0, 1, 0.01, 0.1)
ProcessorEntry::Control::add_state (XMLNode* node) const
{
XMLNode* c = new XMLNode (X_("Object"));
- c->add_property (X_("id"), state_id ());
- c->add_property (X_("visible"), _visible);
+ c->set_property (X_("id"), state_id ());
+ c->set_property (X_("visible"), _visible);
node->add_child_nocopy (*c);
}
{
XMLNode* n = GUIObjectState::get_node (node, state_id ());
if (n) {
- XMLProperty const * p = n->property (X_("visible"));
- set_visible (p && string_is_affirmative (p->value ()));
+ bool visible;
+ if (n->get_property (X_("visible"), visible)) {
+ set_visible (visible);
+ }
} else {
set_visible (false);
}
}
}
-ProcessorEntry::PluginDisplay::PluginDisplay (boost::shared_ptr<ARDOUR::Plugin> p, uint32_t max_height)
- : _plug (p)
+ProcessorEntry::PluginDisplay::PluginDisplay (ProcessorEntry& e, boost::shared_ptr<ARDOUR::Plugin> p, uint32_t max_height)
+ : _entry (e)
+ , _plug (p)
, _surf (0)
, _max_height (max_height)
, _cur_height (1)
, _scroll (false)
{
set_name ("processor prefader");
+ add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK);
+ _plug->DropReferences.connect (_death_connection, invalidator (*this), boost::bind (&PluginDisplay::plugin_going_away, this), gui_context());
_plug->QueueDraw.connect (_qdraw_connection, invalidator (*this),
boost::bind (&Gtk::Widget::queue_draw, this), gui_context ());
+
+ std::string postfix = string_compose(_("\n%1+double-click to toggle inline-display"), Keyboard::tertiary_modifier_name ());
+
+ if (_plug->has_editor()) {
+ ARDOUR_UI_UTILS::set_tooltip (*this,
+ string_compose (_("<b>%1</b>\nDouble-click to show GUI.\n%2+double-click to show generic GUI.%3"), e.name (Wide), Keyboard::primary_modifier_name (), postfix));
+ } else {
+ ARDOUR_UI_UTILS::set_tooltip (*this,
+ string_compose (_("<b>%1</b>\nDouble-click to show generic GUI.%2"), e.name (Wide), postfix));
+ }
}
ProcessorEntry::PluginDisplay::~PluginDisplay ()
}
}
+bool
+ProcessorEntry::PluginDisplay::on_button_press_event (GdkEventButton *ev)
+{
+ assert (_entry.processor ());
+
+ boost::shared_ptr<PluginInsert> pi = boost::dynamic_pointer_cast<PluginInsert> (_entry.processor());
+ // duplicated code :(
+ // consider some tweaks to pass this up to the DnDVBox somehow:
+ // select processor, then call (private)
+ //_entry._parent->processor_button_press_event (ev, &_entry);
+ if (pi && pi->plugin() && pi->plugin()->has_inline_display()
+ && Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)
+ && ev->button == 1
+ && ev->type == GDK_2BUTTON_PRESS) {
+ _entry.toggle_inline_display_visibility ();
+ return true;
+ }
+ else if (Keyboard::is_edit_event (ev) || (ev->button == 1 && ev->type == GDK_2BUTTON_PRESS)) {
+ if (Keyboard::modifier_state_equals (ev->state, Keyboard::SecondaryModifier)) {
+ _entry._parent->generic_edit_processor (_entry.processor ());
+ } else {
+ _entry._parent->edit_processor (_entry.processor ());
+ }
+ return true;
+ }
+ return false;
+}
+
+bool
+ProcessorEntry::PluginDisplay::on_button_release_event (GdkEventButton *ev)
+{
+ return false;
+}
+
void
-ProcessorEntry::PluginDisplay::on_size_request (Gtk::Requisition* req)
+ProcessorEntry::PluginDisplay::on_size_request (Requisition* req)
{
req->width = 56;
req->height = _cur_height;
return true;
}
-ProcessorEntry::LuaPluginDisplay::LuaPluginDisplay (boost::shared_ptr<ARDOUR::LuaProc> p, uint32_t max_height)
- : PluginDisplay (p, max_height)
+ProcessorEntry::LuaPluginDisplay::LuaPluginDisplay (ProcessorEntry& e, boost::shared_ptr<ARDOUR::LuaProc> p, uint32_t max_height)
+ : PluginDisplay (e, p, max_height)
, _luaproc (p)
, _lua_render_inline (0)
{
Cairo::Context ctx (cr);
try {
luabridge::LuaRef rv = (*_lua_render_inline)((Cairo::Context *)&ctx, width, _max_height);
+ lua_gui.collect_garbage_step ();
if (rv.isTable ()) {
uint32_t h = rv[2];
return h;
}
ProcessorBox::ProcessorBox (ARDOUR::Session* sess, boost::function<PluginSelector*()> get_plugin_selector,
- RouteProcessorSelection& rsel, MixerStrip* parent, bool owner_is_mixer)
+ ProcessorSelection& psel, MixerStrip* parent, bool owner_is_mixer)
: _parent_strip (parent)
, _owner_is_mixer (owner_is_mixer)
, ab_direction (true)
, _get_plugin_selector (get_plugin_selector)
, _placement (-1)
, _visible_prefader_processors (0)
- , _rr_selection(rsel)
+ , _p_selection(psel)
, processor_display (drop_targets())
, _redisplay_pending (false)
{
boost::shared_ptr<Processor> processor (new PluginInsert (*_session, p));
if (Config->get_new_plugins_active ()) {
- processor->activate ();
+ processor->enable (true);
}
pl.push_back (processor);
}
}
boost::shared_ptr<Processor> processor (new PluginInsert (*_session, p));
if (Config->get_new_plugins_active ()) {
- processor->activate ();
+ processor->enable (true);
}
pl.push_back (processor);
}
}
- if (!ARDOUR::Profile->get_mixbus()) {
- Gtk::MenuItem* send_menu_item = dynamic_cast<Gtk::MenuItem*>(ActionManager::get_widget("/ProcessorMenu/send_options"));
- if (send_menu_item) {
- if (single_selection && !_route->is_monitor()) {
- Menu* m = single_selection->build_send_options_menu ();
- if (m && !m->items().empty()) {
- send_menu_item->set_submenu (*m);
- send_menu_item->set_sensitive (true);
- } else {
- gtk_menu_item_set_submenu (send_menu_item->gobj(), 0);
- send_menu_item->set_sensitive (false);
- }
+ Gtk::MenuItem* send_menu_item = dynamic_cast<Gtk::MenuItem*>(ActionManager::get_widget("/ProcessorMenu/send_options"));
+ if (send_menu_item) {
+ if (single_selection && !_route->is_monitor()) {
+ Menu* m = single_selection->build_send_options_menu ();
+ if (m && !m->items().empty()) {
+ send_menu_item->set_submenu (*m);
+ send_menu_item->set_sensitive (true);
} else {
+ gtk_menu_item_set_submenu (send_menu_item->gobj(), 0);
send_menu_item->set_sensitive (false);
}
+ } else {
+ send_menu_item->set_sensitive (false);
}
}
const bool sensitive = !processor_display.selection().empty() && ! stub_processor_selected ();
- paste_action->set_sensitive (!_rr_selection.processors.empty());
+ paste_action->set_sensitive (!_p_selection.processors.empty());
cut_action->set_sensitive (sensitive && can_cut ());
copy_action->set_sensitive (sensitive);
delete_action->set_sensitive (sensitive || stub_processor_selected ());
case ProcessorsToggleActive:
for (ProcSelection::iterator i = targets.begin(); i != targets.end(); ++i) {
- if ((*i)->active()) {
- (*i)->deactivate ();
- } else {
- (*i)->activate ();
+ if (!(*i)->display_to_user ()) {
+ assert (0); // these should not be selectable to begin with.
+ continue;
+ }
+ if (!boost::dynamic_pointer_cast<PluginInsert> (*i)) {
+ continue;
+ }
+#ifdef MIXBUS
+ if (boost::dynamic_pointer_cast<PluginInsert> (*i)->is_channelstrip()) {
+ continue;
}
+#endif
+ (*i)->enable (!(*i)->enabled ());
}
break;
int ret = false;
bool selected = processor_display.selected (child);
+ boost::shared_ptr<PluginInsert> pi = boost::dynamic_pointer_cast<PluginInsert> (processor);
+ if (pi && pi->plugin() && pi->plugin()->has_inline_display()
+ && Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)
+ && ev->button == 1
+ && ev->type == GDK_2BUTTON_PRESS) {
+ child->toggle_inline_display_visibility ();
+ return true;
+ }
+
if (processor && (Keyboard::is_edit_event (ev) || (ev->button == 1 && ev->type == GDK_2BUTTON_PRESS))) {
if (_session->engine().connected()) {
) {
/* button2-click with no/appropriate modifiers */
-
- if (processor->active()) {
- processor->deactivate ();
- } else {
- processor->activate ();
- }
+ processor->enable (!processor->enabled ());
}
return false;
} else if (_session->engine().connected () && processor_can_be_edited (processor)) {
if ((*p)->has_editor ()) {
edit_processor (processor);
- } else {
+ } else if (boost::dynamic_pointer_cast<PluginInsert>(processor)->plugin()->parameter_count() > 0) {
generic_edit_processor (processor);
}
}
void
ProcessorBox::weird_plugin_dialog (Plugin& p, Route::ProcessorStreams streams)
{
+ /* XXX this needs to be re-worked!
+ *
+ * With new pin-management "streams" is no longer correct.
+ * p.get_info () is also incorrect for variable i/o plugins (always -1,-1).
+ *
+ * Since pin-management was added, this dialog will only show in a very rare
+ * condition (non-replicated variable i/o configuration failed).
+ *
+ * TODO: simplify the message after the string-freeze is lifted.
+ */
ArdourDialog dialog (_("Plugin Incompatibility"));
Label label;
boost::shared_ptr<Send> send (new Send (*_session, _route->pannable (), _route->mute_master()));
/* make an educated guess at the initial number of outputs for the send */
- ChanCount outs = (_session->master_out())
+ ChanCount outs = (_route->n_outputs().n_audio() && _session->master_out())
? _session->master_out()->n_outputs()
: _route->n_outputs();
(*i)->input_icon.set_ports (p->input_streams());
(*i)->output_icon.set_ports (p->output_streams());
ChanMapping inmap (p->input_streams ());
- ChanMapping outmap (p->input_streams ());
+ ChanMapping outmap (p->output_streams ());
ChanMapping thrumap;
(*i)->routing_icon.set (
p->input_streams(),
return;
}
- _rr_selection.set (node);
+ _p_selection.set (node);
no_processor_redisplay = false;
redisplay_processors ();
}
}
- _rr_selection.set (node);
+ _p_selection.set (node);
}
void
void
ProcessorBox::paste_processors ()
{
- if (_rr_selection.processors.empty()) {
+ if (_p_selection.processors.empty()) {
return;
}
- paste_processor_state (_rr_selection.processors.get_node().children(), boost::shared_ptr<Processor>());
+ paste_processor_state (_p_selection.processors.get_node().children(), boost::shared_ptr<Processor>());
}
void
ProcessorBox::paste_processors (boost::shared_ptr<Processor> before)
{
- if (_rr_selection.processors.empty()) {
+ if (_p_selection.processors.empty()) {
return;
}
- paste_processor_state (_rr_selection.processors.get_node().children(), before);
+ paste_processor_state (_p_selection.processors.get_node().children(), before);
}
void
if (edit_aux_send (processor)) {
return;
}
+ if (!_session->engine().connected()) {
+ return;
+ }
ProcessorWindowProxy* proxy = find_window_proxy (processor);
if (edit_aux_send (processor)) {
return;
}
+ if (!_session->engine().connected()) {
+ return;
+ }
ProcessorWindowProxy* proxy = find_window_proxy (processor);
send DropReferences is about to be deleted, but lets do it anyway.
*/
going_away_connection.disconnect();
+ delete this;
}
ARDOUR::SessionHandlePtr*
{
XMLNode *node;
node = &ProxyBase::get_state();
- node->add_property (X_("custom-ui"), is_custom? X_("yes") : X_("no"));
+ node->set_property (X_("custom-ui"), is_custom);
return *node;
}
XMLNodeList children = node.children ();
XMLNodeList::const_iterator i = children.begin ();
while (i != children.end()) {
- XMLProperty const * prop = (*i)->property (X_("name"));
- if ((*i)->name() == X_("Window") && prop && prop->value() == _name) {
+ std::string name;
+ if ((*i)->name() == X_("Window") && (*i)->get_property (X_("name"), name) && name == _name) {
break;
}
++i;
}
if (i != children.end()) {
- XMLProperty const * prop;
- if ((prop = (*i)->property (X_("custom-ui"))) != 0) {
- want_custom = PBD::string_is_affirmative (prop->value ());
- }
+ (*i)->get_property (X_("custom-ui"), want_custom);
}
return ProxyBase::set_state (node, 0);
}
if (_window && (is_custom != want_custom)) {
/* drop existing window - wrong type */
+ set_state_mask (Gtkmm2ext::WindowProxy::StateMask (state_mask () & ~WindowProxy::Size));
drop_window ();
}
{
if (_window && (is_custom != want_custom)) {
/* drop existing window - wrong type */
+ set_state_mask (Gtkmm2ext::WindowProxy::StateMask (state_mask () & ~WindowProxy::Size));
drop_window ();
}
toggle ();
_window = 0;
WM::Manager::instance().remove (this);
going_away_connection.disconnect();
+ delete this;
}
void