#include <gtkmm/messagedialog.h>
-#include <gtkmm2ext/gtk_ui.h>
-#include <gtkmm2ext/utils.h>
-#include <gtkmm2ext/choice.h>
-#include <gtkmm2ext/utils.h>
-#include <gtkmm2ext/doi.h>
-#include <gtkmm2ext/rgb_macros.h>
+#include "gtkmm2ext/gtk_ui.h"
+#include "gtkmm2ext/menu_elems.h"
+#include "gtkmm2ext/utils.h"
+#include "gtkmm2ext/choice.h"
+#include "gtkmm2ext/utils.h"
+#include "gtkmm2ext/doi.h"
+#include "gtkmm2ext/rgb_macros.h"
+
+#include "widgets/tooltips.h"
#include "ardour/amp.h"
#include "ardour/audio_track.h"
#include "script_selector.h"
#include "send_ui.h"
#include "timers.h"
-#include "tooltips.h"
#include "new_plugin_preset_dialog.h"
#include "pbd/i18n.h"
using namespace Gtk;
using namespace Glib;
using namespace Gtkmm2ext;
+using namespace ArdourWidgets;
ProcessorBox* ProcessorBox::_current_processor_box = 0;
RefPtr<Action> ProcessorBox::paste_action;
}
if (pi->plugin()->has_editor()) {
- ARDOUR_UI_UTILS::set_tooltip (_button,
+ 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::secondary_modifier_name (), postfix));
} else {
- ARDOUR_UI_UTILS::set_tooltip (_button,
+ set_tooltip (_button,
string_compose (_("<b>%1</b>\nDouble-click to show generic GUI.%2"), name (Wide), postfix));
}
return;
if ((send = boost::dynamic_pointer_cast<Send> (_processor)) != 0 &&
!boost::dynamic_pointer_cast<InternalSend>(_processor)) {
if (send->remove_on_disconnect ()) {
- ARDOUR_UI_UTILS::set_tooltip (_button, string_compose ("<b>> %1</b>\nThis (sidechain) send will be removed when disconnected.", _processor->name()));
+ set_tooltip (_button, string_compose ("<b>> %1</b>\nThis (sidechain) send will be removed when disconnected.", _processor->name()));
} else {
- ARDOUR_UI_UTILS::set_tooltip (_button, string_compose ("<b>> %1</b>", _processor->name()));
+ set_tooltip (_button, string_compose ("<b>> %1</b>", _processor->name()));
}
return;
}
}
- ARDOUR_UI_UTILS::set_tooltip (_button, string_compose ("<b>%1</b>", name (Wide)));
+ set_tooltip (_button, string_compose ("<b>%1</b>", name (Wide)));
}
string
}
for (list<Control*>::iterator i = _controls.begin(); i != _controls.end(); ++i) {
- items.push_back (CheckMenuElem ((*i)->name ()));
+ items.push_back (CheckMenuElemNoMnemonic ((*i)->name ()));
Gtk::CheckMenuItem* c = dynamic_cast<Gtk::CheckMenuItem*> (&items.back ());
c->set_active ((*i)->visible ());
c->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &ProcessorEntry::toggle_control_visibility), *i));
_button.signal_clicked.connect (sigc::mem_fun (*this, &Control::button_clicked));
_button.signal_led_clicked.connect (sigc::mem_fun (*this, &Control::button_clicked_event));
- // dup. currently timers are used :(
- //c->Changed.connect (_connection, MISSING_INVALIDATOR, boost::bind (&Control::control_changed, this), gui_context ());
+ c->Changed.connect (_connections, invalidator (*this), boost::bind (&Control::control_changed, this), gui_context ());
+ if (c->alist ()) {
+ c->alist()->automation_state_changed.connect (_connections, invalidator (*this), boost::bind (&Control::control_automation_state_changed, this), gui_context());
+ control_automation_state_changed ();
+ }
} else {
_slider.show ();
const ARDOUR::ParameterDescriptor& desc = c->desc();
- double const lo = c->internal_to_interface(desc.lower);
- double const up = c->internal_to_interface(desc.upper);
- double const normal = c->internal_to_interface(desc.normal);
- double smallstep = desc.smallstep;
- double largestep = desc.largestep;
-
- if (smallstep == 0.0) {
- smallstep = up / 1000.;
- } else {
- smallstep = c->internal_to_interface(desc.lower + smallstep);
- }
-
- if (largestep == 0.0) {
- largestep = up / 40.;
- } else {
- largestep = c->internal_to_interface(desc.lower + largestep);
- }
+ double const lo = c->internal_to_interface (desc.lower);
+ double const up = c->internal_to_interface (desc.upper);
+ double const normal = c->internal_to_interface (desc.normal);
+ double const smallstep = c->internal_to_interface (desc.lower + desc.smallstep);
+ double const largestep = c->internal_to_interface (desc.lower + desc.largestep);
_adjustment.set_lower (lo);
_adjustment.set_upper (up);
_slider.set_default_value (normal);
_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &Control::slider_adjusted));
- // dup. currently timers are used :(
- //c->Changed.connect (_connection, MISSING_INVALIDATOR, boost::bind (&Control::control_changed, this), gui_context ());
+ c->Changed.connect (_connections, invalidator (*this), boost::bind (&Control::control_changed, this), gui_context ());
+ if (c->alist ()) {
+ c->alist()->automation_state_changed.connect (_connections, invalidator (*this), boost::bind (&Control::control_automation_state_changed, this), gui_context());
+ control_automation_state_changed ();
+ }
}
- // yuck, do we really need to do this?
- // according to c404374 this is only needed for send automation
- timer_connection = Timers::rapid_connect (sigc::mem_fun (*this, &Control::control_changed));
-
control_changed ();
set_tooltip ();
ProcessorEntry::Control::~Control ()
{
- timer_connection.disconnect ();
}
void
std::string tt = _name + ": " + ARDOUR::value_as_string (c->desc(), c->get_value ());
string sm = Gtkmm2ext::markup_escape_text (tt);
_slider_persistant_tooltip.set_tip (sm);
- ARDOUR_UI_UTILS::set_tooltip (_button, sm);
+ ArdourWidgets::set_tooltip (_button, sm);
}
void
button_clicked ();
}
+void
+ProcessorEntry::Control::control_automation_state_changed ()
+{
+ boost::shared_ptr<AutomationControl> c = _control.lock ();
+ if (!c) {
+ return;
+ }
+ bool x = c->alist()->automation_state() & Play;
+ if (c->toggled ()) {
+ _button.set_sensitive (!x);
+ } else {
+ _slider.set_sensitive (!x);
+ }
+}
+
void
ProcessorEntry::Control::control_changed ()
{
_ignore_ui_adjustment = true;
if (c->toggled ()) {
-
_button.set_active (c->get_value() > 0.5);
-
} else {
- // as long as rapid timers are used, only update the tooltip
- // if the value has changed.
+ // Note: the _slider watches the controllable by itself
const double nval = c->internal_to_interface (c->get_value ());
if (_adjustment.get_value() != nval) {
_adjustment.set_value (nval);
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,
+ 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,
+ set_tooltip (*this,
string_compose (_("<b>%1</b>\nDouble-click to show generic GUI.%2"), e.name (Wide), postfix));
}
}
, ab_direction (true)
, _get_plugin_selector (get_plugin_selector)
, _placement (-1)
- , _visible_prefader_processors (0)
, _p_selection(psel)
, processor_display (drop_targets())
, _redisplay_pending (false)
);
}
- ARDOUR_UI_UTILS::set_tooltip (processor_display, _("Right-click to add/remove/edit\nplugins,inserts,sends and more"));
+ set_tooltip (processor_display, _("Right-click to add/remove/edit\nplugins,inserts,sends and more"));
}
ProcessorBox::~ProcessorBox ()
boost::shared_ptr<Processor> p = find_drop_position (position);
- list<ProcessorEntry*> children = source->selection ();
+ list<ProcessorEntry*> children = source->selection (true);
list<boost::shared_ptr<Processor> > procs;
for (list<ProcessorEntry*>::const_iterator i = children.begin(); i != children.end(); ++i) {
if ((*i)->processor ()) {
for (RouteList::iterator r = rl->begin(); r != rl->end(); ++r) {
if (!_route->internal_send_for (*r) && *r != _route) {
- items.push_back (MenuElem ((*r)->name(), sigc::bind (sigc::ptr_fun (ProcessorBox::rb_choose_aux), boost::weak_ptr<Route>(*r))));
+ items.push_back (MenuElemNoMnemonic ((*r)->name(), sigc::bind (sigc::ptr_fun (ProcessorBox::rb_choose_aux), boost::weak_ptr<Route>(*r))));
}
}
int x, y;
processor_display.get_pointer (x, y);
_placement = processor_display.add_placeholder (y);
-
- if (_visible_prefader_processors == 0 && _placement > 0) {
- --_placement;
- }
}
bool
}
}
}
+ /* add next processor below the currently added.
+ * Note: placement < 0: add the bottom */
+ if (_placement >= 0) {
+ ++_placement;
+ }
}
return false;
ProcessorBox::redisplay_processors ()
{
ENSURE_GUI_THREAD (*this, &ProcessorBox::redisplay_processors);
- bool fader_seen;
if (no_processor_redisplay) {
return;
processor_display.clear ();
- _visible_prefader_processors = 0;
- fader_seen = false;
-
- _route->foreach_processor (sigc::bind (sigc::mem_fun (*this, &ProcessorBox::help_count_visible_prefader_processors),
- &_visible_prefader_processors, &fader_seen));
-
_route->foreach_processor (sigc::mem_fun (*this, &ProcessorBox::add_processor_to_display));
_route->foreach_processor (sigc::mem_fun (*this, &ProcessorBox::maybe_add_processor_to_ui_list));
_route->foreach_processor (sigc::mem_fun (*this, &ProcessorBox::maybe_add_processor_pin_mgr));
wp->set_state (*ui_xml, 0);
}
- void* existing_ui = p->get_ui ();
-
- if (existing_ui) {
- wp->use_window (*(reinterpret_cast<Gtk::Window*>(existing_ui)));
- }
-
p->set_window_proxy (wp);
WM::Manager::instance().register_window (wp);
}
p->set_pingmgr_proxy (wp);
WM::Manager::instance().register_window (wp);
}
-void
-ProcessorBox::help_count_visible_prefader_processors (boost::weak_ptr<Processor> p, uint32_t* cnt, bool* amp_seen)
-{
- boost::shared_ptr<Processor> processor (p.lock ());
-
- if (processor && ( processor->display_to_user()
-#ifndef NDEBUG
- || show_all_processors
-#endif
- )
- ) {
-
- if (boost::dynamic_pointer_cast<Amp>(processor) &&
- boost::dynamic_pointer_cast<Amp>(processor)->gain_control()->parameter().type() == GainAutomation) {
- *amp_seen = true;
- } else {
- if (!*amp_seen) {
- (*cnt)++;
- }
- }
- }
-}
void
ProcessorBox::add_processor_to_display (boost::weak_ptr<Processor> p)
name_prompter.get_result (result);
if (result.length()) {
- int tries = 0;
- string test = result;
-
- while (tries < 100) {
- if (_session->io_name_is_legal (test)) {
- result = test;
- break;
- }
- tries++;
-
- test = string_compose ("%1-%2", result, tries);
- }
-
- if (tries < 100) {
- processor->set_name (result);
- } else {
- /* unlikely! */
- ARDOUR_UI::instance()->popup_error
- (string_compose (_("At least 100 IO objects exist with a name like %1 - name not changed"), result));
- }
+ int tries = 0;
+ string test = result;
+
+ while (tries < 100) {
+ if (_session->io_name_is_legal (test)) {
+ result = test;
+ break;
+ }
+ tries++;
+
+ test = string_compose ("%1-%2", result, tries);
+ }
+
+ if (tries < 100) {
+ processor->set_name (result);
+ } else {
+ /* unlikely! */
+ ARDOUR_UI::instance()->popup_error
+ (string_compose (_("At least 100 IO objects exist with a name like %1 - name not changed"), result));
+ }
}
break;
}
IOProcessor::prepare_for_reset (n, s->name());
- if (s->set_state (n, Stateful::loading_state_version)) {
- delete s;
- return;
- }
+ if (s->set_state (n, Stateful::loading_state_version)) {
+ delete s;
+ return;
+ }
p.reset (s);
IOProcessor::prepare_for_reset (n, s->name());
- if (s->set_state (n, Stateful::loading_state_version)) {
- delete s;
- return;
- }
+ if (s->set_state (n, Stateful::loading_state_version)) {
+ delete s;
+ return;
+ }
p.reset (s);
} else if (type->value() == "return") {
XMLNode n (**niter);
- Return* r = new Return (*_session);
+ Return* r = new Return (*_session);
IOProcessor::prepare_for_reset (n, r->name());
- if (r->set_state (n, Stateful::loading_state_version)) {
- delete r;
- return;
- }
+ if (r->set_state (n, Stateful::loading_state_version)) {
+ delete r;
+ return;
+ }
p.reset (r);
void
ProcessorBox::get_selected_processors (ProcSelection& processors) const
{
- const list<ProcessorEntry*> selection = processor_display.selection ();
+ const list<ProcessorEntry*> selection = processor_display.selection (true);
for (list<ProcessorEntry*>::const_iterator i = selection.begin(); i != selection.end(); ++i) {
processors.push_back ((*i)->processor ());
}
ProcessorBox::set_processor_ui (boost::shared_ptr<Processor> p, Gtk::Window* w)
{
assert (p->window_proxy());
- p->set_ui (w);
p->window_proxy()->use_window (*w);
}
: WM::ProxyBase (name, string())
, _processor_box (box)
, _processor (processor)
- , is_custom (false)
- , want_custom (false)
+ , is_custom (true)
+ , want_custom (true)
{
boost::shared_ptr<Processor> p = _processor.lock ();
if (!p) {
return;
}
p->DropReferences.connect (going_away_connection, MISSING_INVALIDATOR, boost::bind (&ProcessorWindowProxy::processor_going_away, this), gui_context());
+
+ p->ToggleUI.connect (gui_connections, invalidator (*this), boost::bind (&ProcessorWindowProxy::show_the_right_window, this, false), gui_context());
+ p->ShowUI.connect (gui_connections, invalidator (*this), boost::bind (&ProcessorWindowProxy::show_the_right_window, this, true), gui_context());
+ p->HideUI.connect (gui_connections, invalidator (*this), boost::bind (&ProcessorWindowProxy::hide, this), gui_context());
}
ProcessorWindowProxy::~ProcessorWindowProxy()
void
ProcessorWindowProxy::processor_going_away ()
{
+ gui_connections.drop_connections ();
delete _window;
_window = 0;
WM::Manager::instance().remove (this);
}
void
-ProcessorWindowProxy::show_the_right_window ()
+ProcessorWindowProxy::show_the_right_window (bool show_not_toggle)
{
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 && fully_visible () && show_not_toggle) {
+ return;
+ }
toggle ();
}