ProcessorEntry::set_enum_width (Width w)
{
_width = w;
+ _button.set_text (name (_width));
}
void
{
cairo_t* cr = gdk_cairo_create (get_window()->gobj());
- cairo_set_line_width (cr, 1);
+ cairo_rectangle (cr, ev->area.x, ev->area.y, ev->area.width, ev->area.height);
+ cairo_clip (cr);
+
+ cairo_set_line_width (cr, 1.5);
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
- double const width = ev->area.width;
- double const height = ev->area.height;
+ Gtk::Allocation a = get_allocation();
+ double const width = a.get_width();
+ double const height = a.get_height();
Gdk::Color const bg = get_style()->get_bg (STATE_NORMAL);
cairo_set_source_rgb (cr, bg.get_red_p (), bg.get_green_p (), bg.get_blue_p ());
Gdk::Color const fg = get_style()->get_fg (STATE_NORMAL);
cairo_set_source_rgb (cr, fg.get_red_p (), fg.get_green_p (), fg.get_blue_p ());
- cairo_move_to (cr, width * 0.3, height);
- cairo_line_to (cr, width * 0.3, height * 0.5);
- cairo_line_to (cr, width * 0.7, height * 0.5);
- cairo_line_to (cr, width * 0.7, height);
- cairo_move_to (cr, width * 0.5, height * 0.5);
- cairo_line_to (cr, width * 0.5, 0);
+ const float si_l = rint(width * 0.3) + .5;
+ const float si_c = rint(width * 0.5) + .5;
+ const float si_r = rint(width * 0.7) + .5;
+ const float si_m = rint(height * 0.5) + .5;
+
+ cairo_move_to (cr, si_l, height);
+ cairo_line_to (cr, si_l, si_m);
+ cairo_line_to (cr, si_r, si_m);
+ cairo_line_to (cr, si_r, height);
+
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
+ cairo_move_to (cr, si_c, si_m);
+ cairo_line_to (cr, si_c, 0);
cairo_stroke (cr);
return true;
_route->foreach_processor (sigc::mem_fun (*this, &ProcessorBox::add_processor_to_display));
- for (list<ProcessorWindowProxy*>::iterator i = _processor_window_info.begin(); i != _processor_window_info.end(); ++i) {
+ for (ProcessorWindowProxies::iterator i = _processor_window_info.begin(); i != _processor_window_info.end(); ++i) {
(*i)->marked = false;
}
/* trim dead wood from the processor window proxy list */
- list<ProcessorWindowProxy*>::iterator i = _processor_window_info.begin();
+ ProcessorWindowProxies::iterator i = _processor_window_info.begin();
while (i != _processor_window_info.end()) {
- list<ProcessorWindowProxy*>::iterator j = i;
+ ProcessorWindowProxies::iterator j = i;
++j;
- if (!(*i)->marked) {
+ if (!(*i)->valid()) {
+
WM::Manager::instance().remove (*i);
delete *i;
_processor_window_info.erase (i);
- }
+
+ } else if (!(*i)->marked) {
+
+ /* this processor is no longer part of this processor
+ * box.
+ *
+ * that could be because it was deleted or it could be
+ * because the route being displayed in the parent
+ * strip changed.
+ *
+ * The latter only happens with the editor mixer strip.
+ */
+
+ if (is_editor_mixer_strip()) {
+
+ /* editor mixer strip .. DO NOTHING
+ *
+ * note: the processor window stays visible if
+ * it is already visible
+ */
+ } else {
+ (*i)->hide ();
+ WM::Manager::instance().remove (*i);
+ delete *i;
+ _processor_window_info.erase (i);
+ }
+ }
i = j;
}
return;
}
- list<ProcessorWindowProxy*>::iterator i = _processor_window_info.begin ();
+ ProcessorWindowProxies::iterator i = _processor_window_info.begin ();
while (i != _processor_window_info.end()) {
boost::shared_ptr<Processor> t = (*i)->processor().lock ();
}
if (
- (boost::dynamic_pointer_cast<Send> (processor) && !boost::dynamic_pointer_cast<InternalSend> (processor))||
+ boost::dynamic_pointer_cast<Send> (processor) ||
boost::dynamic_pointer_cast<Return> (processor) ||
boost::dynamic_pointer_cast<PluginInsert> (processor) ||
boost::dynamic_pointer_cast<PortInsert> (processor)
boost::shared_ptr<PortInsert> port_insert;
Window* gidget = 0;
+ /* This method may or may not return a Window, but if it does not it
+ * will modify the parent mixer strip appearance layout to allow
+ * "editing" the @param processor that was passed in.
+ *
+ * So for example, if the processor is an Amp (gain), the parent strip
+ * will be forced back into a model where the fader controls the main gain.
+ * If the processor is a send, then we map the send controls onto the
+ * strip.
+ *
+ * Plugins and others will return a window for control.
+ */
+
if (boost::dynamic_pointer_cast<AudioTrack>(_route) != 0) {
if (boost::dynamic_pointer_cast<AudioTrack> (_route)->freeze_state() == AudioTrack::Frozen) {
if (boost::dynamic_pointer_cast<InternalSend> (processor) == 0) {
gidget = new SendUIWindow (send, _session);
-
- } else {
- /* assign internal send to main fader */
-
- if (_parent_strip) {
- if (_parent_strip->current_delivery() == send) {
- _parent_strip->revert_to_default_display ();
- } else {
- _parent_strip->show_send(send);
- }
- }
}
} else if ((retrn = boost::dynamic_pointer_cast<Return> (processor)) != 0) {
} else if ((port_insert = boost::dynamic_pointer_cast<PortInsert> (processor)) != 0) {
if (!_session->engine().connected()) {
- MessageDialog msg ( _("Not connected to JACK - no I/O changes are possible"));
+ MessageDialog msg ( _("Not connected to audio engine - no I/O changes are possible"));
msg.run ();
return 0;
}
act = ActionManager::register_action (popup_act_grp, X_("newinsert"), _("New Insert"),
sigc::ptr_fun (ProcessorBox::rb_choose_insert));
- ActionManager::jack_sensitive_actions.push_back (act);
+ ActionManager::engine_sensitive_actions.push_back (act);
act = ActionManager::register_action (popup_act_grp, X_("newsend"), _("New External Send ..."),
sigc::ptr_fun (ProcessorBox::rb_choose_send));
- ActionManager::jack_sensitive_actions.push_back (act);
+ ActionManager::engine_sensitive_actions.push_back (act);
ActionManager::register_action (popup_act_grp, X_("newaux"), _("New Aux Send ..."));
_current_processor_box->for_selected_processors (&ProcessorBox::edit_processor);
}
+bool
+ProcessorBox::edit_aux_send (boost::shared_ptr<Processor> processor)
+{
+ if (boost::dynamic_pointer_cast<InternalSend> (processor) == 0) {
+ return false;
+ }
+
+ if (_parent_strip) {
+ boost::shared_ptr<Send> send = boost::dynamic_pointer_cast<Send> (processor);
+ if (_parent_strip->current_delivery() == send) {
+ _parent_strip->revert_to_default_display ();
+ } else {
+ _parent_strip->show_send(send);
+ }
+ }
+ return true;
+}
+
void
ProcessorBox::edit_processor (boost::shared_ptr<Processor> processor)
{
if (!processor) {
return;
}
-
+ if (edit_aux_send (processor)) {
+ return;
+ }
+
ProcessorWindowProxy* proxy = find_window_proxy (processor);
if (proxy) {
if (!processor) {
return;
}
-
+ if (edit_aux_send (processor)) {
+ return;
+ }
+
ProcessorWindowProxy* proxy = find_window_proxy (processor);
if (proxy) {
maker += " ...";
}
- return string_compose(_("%1: %2 (by %3)"), _route->name(), pi->name(), maker);
+ SessionObject* owner = pi->owner();
+
+ if (owner) {
+ return string_compose(_("%1: %2 (by %3)"), owner->name(), pi->name(), maker);
+ } else {
+ return string_compose(_("%2 (by %3)"), pi->name(), maker);
+ }
}
/** @param p Processor.
entry->add_control_state (proc);
}
+bool
+ProcessorBox::is_editor_mixer_strip() const
+{
+ return _parent_strip && !_parent_strip->mixer_owned();
+}
+
ProcessorWindowProxy::ProcessorWindowProxy (string const & name, ProcessorBox* box, boost::weak_ptr<Processor> processor)
: WM::ProxyBase (name, string())
, marked (false)
, _processor (processor)
, is_custom (false)
, want_custom (false)
+ , _valid (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());
+}
+ProcessorWindowProxy::~ProcessorWindowProxy()
+{
+ /* processor window proxies do not own the windows they create with
+ * ::get(), so set _window to null before the normal WindowProxy method
+ * deletes it.
+ */
+ _window = 0;
+}
+
+void
+ProcessorWindowProxy::processor_going_away ()
+{
+ delete _window;
+ _window = 0;
+ _valid = false;
+ /* should be no real reason to do this, since the object that would
+ send DropReferences is about to be deleted, but lets do it anyway.
+ */
+ going_away_connection.disconnect();
}
ARDOUR::SessionHandlePtr*
return 0;
}
+bool
+ProcessorWindowProxy::valid() const
+{
+ return _valid;
+}
+
XMLNode&
ProcessorWindowProxy::get_state () const
{