Highlight a send processor entry differently when it the mixer strip's fader is being used to control it. Fixes #3659.

git-svn-id: svn://localhost/ardour2/branches/3.0@8440 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Carl Hetherington 2011-01-04 23:26:59 +00:00
parent a7d465fcb7
commit 4a9f3173ee
6 changed files with 112 additions and 23 deletions

View File

@ -1141,6 +1141,13 @@ style "automation_track_controls_base"
bg[PRELIGHT] = { 0.22, 0.22, 0.29 }
}
# Fader used for sends in processor boxes
style "send_fader"
{
bg[NORMAL] = { 0.0, 0.0, 0.0 }
bg[ACTIVE] = { 0.0, 0.0, 0.0 }
}
# Plugin Editors
style "plugin_slider"
{
@ -1216,15 +1223,15 @@ style "processor_list_display"
font_name = "@FONT_SMALLER@"
bg[NORMAL] = { 0, 0, 0 }
# A selected processor
bg[SELECTED] = { 0, 0.5, 0.9 }
# A send processor whose level is being controlled by the fader
bg[ACTIVE] = { 0.19, 0.97, 0.69 }
fg[ACTIVE] = { 0.0, 0.0, 0.0 }
GtkCheckButton::indicator-size = 10
GtkCheckButton::indicator-spacing = 0
}
style "inspector_processor_list_display" = "processor_list_display"
{
base[SELECTED] = { 0.3, 0.3, 0.3 }
}
# MixerPanZone:
#
# the NORMAL fg color is used for the pan puck
@ -1776,8 +1783,6 @@ widget "*ConnectionEditorNotebook" style:highest "io_selector_notebook"
widget "*ConnectionEditorNotebookTab" style:highest "io_selector_notebook"
widget "*ConnectionEditorFrame" style:highest "base_frame"
widget "*RouteParamsListDisplay" style:highest "inspector_track_list_display"
widget "*RouteParamsPreListDisplay" style:highest "inspector_processor_list_display"
widget "*RouteParamsPostListDisplay" style:highest "inspector_processor_list_display"
widget "*TearOffArrow" style:highest "tearoff_arrow"
widget "*RouteParamsTitleButton" style:highest "medium_text"
widget "*RouteParamsTitleLabel" style:highest "medium_text"
@ -1869,3 +1874,4 @@ widget "*SoloLEDLabel" style:highest "very_small_text"
widget "*RouteNameEditorEntry" style:highest "text_cell_entry"
widget "*RegionNameEditorEntry" style:highest "text_cell_entry"
widget "*SendFader*" style:highest "send_fader"

View File

@ -1716,6 +1716,13 @@ MixerStrip::drop_send ()
output_button.set_sensitive (true);
}
void
MixerStrip::set_current_delivery (boost::shared_ptr<Delivery> d)
{
_current_delivery = d;
DeliveryChanged (_current_delivery);
}
void
MixerStrip::show_send (boost::shared_ptr<Send> send)
{
@ -1723,7 +1730,7 @@ MixerStrip::show_send (boost::shared_ptr<Send> send)
drop_send ();
_current_delivery = send;
set_current_delivery (send);
send->set_metering (true);
_current_delivery->DropReferences.connect (send_gone_connection, invalidator (*this), boost::bind (&MixerStrip::revert_to_default_display, this), gui_context());
@ -1752,7 +1759,7 @@ MixerStrip::revert_to_default_display ()
drop_send ();
_current_delivery = _route->main_outs();
set_current_delivery (_route->main_outs ());
gain_meter().set_controls (_route, _route->shared_peak_meter(), _route->amp());
gain_meter().setup_meters ();

View File

@ -103,7 +103,10 @@ class MixerStrip : public RouteUI, public Gtk::EventBox
return _mixer_owned;
}
sigc::signal<void> WidthChanged;
sigc::signal<void> WidthChanged;
/** The delivery that we are handling the level for with our fader has changed */
PBD::Signal1<void, boost::weak_ptr<ARDOUR::Delivery> > DeliveryChanged;
static sigc::signal<void,boost::shared_ptr<ARDOUR::Route> > SwitchIO;
static PBD::Signal1<void,MixerStrip*> CatchDeletion;
@ -265,7 +268,10 @@ class MixerStrip : public RouteUI, public Gtk::EventBox
void engine_stopped();
void switch_io (boost::shared_ptr<ARDOUR::Route>);
void set_current_delivery (boost::shared_ptr<ARDOUR::Delivery>);
boost::shared_ptr<ARDOUR::Delivery> _current_delivery;
void revert_to_default_display ();
void drop_send ();

View File

@ -228,6 +228,7 @@ SendProcessorEntry::SendProcessorEntry (boost::shared_ptr<Send> s, Width w)
_fader (_slider, &_adjustment, 0, false),
_ignore_gain_change (false)
{
_fader.set_name ("SendFader");
_fader.set_controllable (_send->amp()->gain_control ());
_vbox.pack_start (_fader);
@ -310,6 +311,12 @@ ProcessorBox::ProcessorBox (ARDOUR::Session* sess, boost::function<PluginSelecto
processor_display.Reordered.connect (sigc::mem_fun (*this, &ProcessorBox::reordered));
processor_display.DropFromAnotherBox.connect (sigc::mem_fun (*this, &ProcessorBox::object_drop));
processor_display.SelectionChanged.connect (sigc::mem_fun (*this, &ProcessorBox::selection_changed));
if (parent) {
parent->DeliveryChanged.connect (
_mixer_strip_connections, invalidator (*this), ui_bind (&ProcessorBox::mixer_strip_delivery_changed, this, _1), gui_context ()
);
}
}
ProcessorBox::~ProcessorBox ()
@ -323,15 +330,23 @@ ProcessorBox::set_route (boost::shared_ptr<Route> r)
return;
}
connections.drop_connections();
_route_connections.drop_connections();
/* new route: any existing block on processor redisplay must be meaningless */
no_processor_redisplay = false;
_route = r;
_route->processors_changed.connect (connections, invalidator (*this), ui_bind (&ProcessorBox::route_processors_changed, this, _1), gui_context());
_route->DropReferences.connect (connections, invalidator (*this), boost::bind (&ProcessorBox::route_going_away, this), gui_context());
_route->PropertyChanged.connect (connections, invalidator (*this), ui_bind (&ProcessorBox::route_property_changed, this, _1), gui_context());
_route->processors_changed.connect (
_route_connections, invalidator (*this), ui_bind (&ProcessorBox::route_processors_changed, this, _1), gui_context()
);
_route->DropReferences.connect (
_route_connections, invalidator (*this), boost::bind (&ProcessorBox::route_going_away, this), gui_context()
);
_route->PropertyChanged.connect (
_route_connections, invalidator (*this), ui_bind (&ProcessorBox::route_property_changed, this, _1), gui_context()
);
redisplay_processors ();
}
@ -2031,6 +2046,27 @@ ProcessorBox::set_processor_ui (boost::shared_ptr<Processor> p, Gtk::Window* w)
assert (false);
}
void
ProcessorBox::mixer_strip_delivery_changed (boost::weak_ptr<Delivery> w)
{
boost::shared_ptr<Delivery> d = w.lock ();
if (!d) {
return;
}
list<ProcessorEntry*> children = processor_display.children ();
list<ProcessorEntry*>::const_iterator i = children.begin();
while (i != children.end() && (*i)->processor() != d) {
++i;
}
if (i == children.end()) {
processor_display.set_active (0);
} else {
processor_display.set_active (*i);
}
}
ProcessorWindowProxy::ProcessorWindowProxy (
string const & name,
XMLNode const * node,
@ -2056,3 +2092,4 @@ ProcessorWindowProxy::show ()
_processor_box->toggle_edit_processor (p);
}

View File

@ -189,7 +189,8 @@ class ProcessorBox : public Gtk::HBox, public PluginInterestedObject, public ARD
MixerStrip* _parent_strip; // null if in RouteParamsUI
bool _owner_is_mixer;
bool ab_direction;
PBD::ScopedConnectionList connections;
PBD::ScopedConnectionList _mixer_strip_connections;
PBD::ScopedConnectionList _route_connections;
boost::function<PluginSelector*()> _get_plugin_selector;
@ -321,6 +322,8 @@ class ProcessorBox : public Gtk::HBox, public PluginInterestedObject, public ARD
bool one_processor_can_be_edited ();
bool processor_can_be_edited (boost::shared_ptr<ARDOUR::Processor>);
void mixer_strip_delivery_changed (boost::weak_ptr<ARDOUR::Delivery>);
};
#endif /* __ardour_gtk_processor_box__ */

View File

@ -42,7 +42,7 @@ template <class T>
class DnDVBox : public Gtk::EventBox
{
public:
DnDVBox () : _drag_icon (0), _expecting_unwanted_button_event (false), _drag_placeholder (0)
DnDVBox () : _active (0), _drag_icon (0), _expecting_unwanted_button_event (false), _drag_placeholder (0)
{
_targets.push_back (Gtk::TargetEntry ("processor"));
@ -107,6 +107,21 @@ public:
return _selection;
}
/** Set the `active' child; this is simply a child which is set to have the Gtk
* STATE_ACTIVE for whatever purposes the client may have.
* @param c Child, or 0 for none.
*/
void set_active (T* c) {
T* old_active = _active;
_active = c;
if (old_active) {
setup_child_state (old_active);
}
if (_active) {
setup_child_state (_active);
}
}
/** @param Child
* @return true if the child is selected, otherwise false.
*/
@ -468,27 +483,41 @@ private:
return ButtonRelease (ev, child); /* EMIT SIGNAL */
}
/** Setup a child's GTK state correctly */
void setup_child_state (T* c)
{
assert (c);
if (c == _active) {
c->action_widget().set_state (Gtk::STATE_ACTIVE);
} else if (selected (c)) {
c->action_widget().set_state (Gtk::STATE_SELECTED);
} else {
c->action_widget().set_state (Gtk::STATE_NORMAL);
}
}
void clear_selection ()
{
for (typename std::list<T*>::iterator i = _selection.begin(); i != _selection.end(); ++i) {
(*i)->action_widget().set_state (Gtk::STATE_NORMAL);
}
std::list<T*> old_selection = _selection;
_selection.clear ();
for (typename std::list<T*>::iterator i = old_selection.begin(); i != old_selection.end(); ++i) {
setup_child_state (*i);
}
}
void add_to_selection (T* child)
{
child->action_widget().set_state (Gtk::STATE_SELECTED);
_selection.push_back (child);
setup_child_state (child);
}
void remove_from_selection (T* child)
{
typename std::list<T*>::iterator x = find (_selection.begin(), _selection.end(), child);
if (x != _selection.end()) {
child->action_widget().set_state (Gtk::STATE_NORMAL);
_selection.erase (x);
setup_child_state (*x);
}
}
@ -510,6 +539,7 @@ private:
std::list<Gtk::TargetEntry> _targets;
std::list<T*> _children;
std::list<T*> _selection;
T* _active;
Gtk::Window* _drag_icon;
bool _expecting_unwanted_button_event;
/** A blank label used as a placeholder to indicate where a dragged item would