diff --git a/gtk2_ardour/mixer_strip.cc b/gtk2_ardour/mixer_strip.cc index 52b84d98a1..80fd6f5c38 100644 --- a/gtk2_ardour/mixer_strip.cc +++ b/gtk2_ardour/mixer_strip.cc @@ -498,7 +498,7 @@ MixerStrip::set_route (boost::shared_ptr rt) add_events (Gdk::BUTTON_RELEASE_MASK); - processor_box.show(); + processor_box.show (); if (!route()->is_master() && !route()->is_monitor()) { /* we don't allow master or control routes to be hidden */ @@ -513,7 +513,6 @@ MixerStrip::set_route (boost::shared_ptr rt) button_table.show(); middle_button_table.show(); bottom_button_table.show(); - processor_box.show_all (); gpm.show_all (); gain_meter_alignment.show (); gain_unit_button.show(); diff --git a/gtk2_ardour/processor_box.cc b/gtk2_ardour/processor_box.cc index 2eaeeb83f7..8bf4afc1ca 100644 --- a/gtk2_ardour/processor_box.cc +++ b/gtk2_ardour/processor_box.cc @@ -95,10 +95,10 @@ RefPtr ProcessorBox::edit_action; Glib::RefPtr SendProcessorEntry::_slider; ProcessorEntry::ProcessorEntry (boost::shared_ptr p, Width w) - : _processor (p) + : _position (PreFader) + , _processor (p) , _width (w) , _visual_state (Gtk::STATE_NORMAL) - , _position (PreFader) { _hbox.pack_start (_active, false, false); _event_box.add (_name); @@ -122,6 +122,13 @@ ProcessorEntry::ProcessorEntry (boost::shared_ptr p, Width w) _active.set_active (_processor->active ()); _active.signal_toggled().connect (sigc::mem_fun (*this, &ProcessorEntry::active_toggled)); + + _frame.show (); + _vbox.show (); + _hbox.show (); + _event_box.show (); + _name.show (); + _active.show (); _processor->ActiveChanged.connect (active_connection, invalidator (*this), boost::bind (&ProcessorEntry::processor_active_changed, this), gui_context()); _processor->PropertyChanged.connect (name_connection, invalidator (*this), ui_bind (&ProcessorEntry::processor_property_changed, this, _1), gui_context()); @@ -349,6 +356,82 @@ SendProcessorEntry::set_pixel_width (int p) _fader.set_fader_length (p); } +PluginInsertProcessorEntry::PluginInsertProcessorEntry (boost::shared_ptr p, Width w) + : ProcessorEntry (p, w) + , _plugin_insert (p) +{ + p->SplittingChanged.connect ( + _splitting_connection, invalidator (*this), ui_bind (&PluginInsertProcessorEntry::plugin_insert_splitting_changed, this), gui_context() + ); + + _splitting_icon.set_size_request (-1, 12); + + _vbox.pack_start (_splitting_icon); + _vbox.reorder_child (_splitting_icon, 0); + + plugin_insert_splitting_changed (); +} + +void +PluginInsertProcessorEntry::plugin_insert_splitting_changed () +{ + if (_plugin_insert->splitting ()) { + _splitting_icon.show (); + } else { + _splitting_icon.hide (); + } +} + +void +PluginInsertProcessorEntry::setup_visuals () +{ + switch (_position) { + case PreFader: + _splitting_icon.set_name ("ProcessorPreFader"); + break; + + case Fader: + _splitting_icon.set_name ("ProcessorFader"); + break; + + case PostFader: + _splitting_icon.set_name ("ProcessorPostFader"); + break; + } + + ProcessorEntry::setup_visuals (); +} + +bool +PluginInsertProcessorEntry::SplittingIcon::on_expose_event (GdkEventExpose* ev) +{ + cairo_t* cr = gdk_cairo_create (get_window()->gobj()); + + cairo_set_line_width (cr, 1); + + double const width = ev->area.width; + double const height = ev->area.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 ()); + + cairo_rectangle (cr, 0, 0, width, height); + cairo_fill (cr); + + 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); + cairo_stroke (cr); + + return true; +} + ProcessorBox::ProcessorBox (ARDOUR::Session* sess, boost::function get_plugin_selector, RouteRedirectSelection& rsel, MixerStrip* parent, bool owner_is_mixer) : _parent_strip (parent) @@ -388,6 +471,9 @@ ProcessorBox::ProcessorBox (ARDOUR::Session* sess, boost::functionDeliveryChanged.connect ( _mixer_strip_connections, invalidator (*this), ui_bind (&ProcessorBox::mixer_strip_delivery_changed, this, _1), gui_context () @@ -1042,8 +1128,6 @@ ProcessorBox::redisplay_processors () _route->foreach_processor (sigc::mem_fun (*this, &ProcessorBox::add_processor_to_display)); - build_processor_tooltip (processor_eventbox, _("Inserts, sends & plugins:")); - for (list::iterator i = _processor_window_proxies.begin(); i != _processor_window_proxies.end(); ++i) { (*i)->marked = false; } @@ -1128,12 +1212,16 @@ ProcessorBox::add_processor_to_display (boost::weak_ptr p) } boost::shared_ptr send = boost::dynamic_pointer_cast (processor); + boost::shared_ptr plugin_insert = boost::dynamic_pointer_cast (processor); ProcessorEntry* e = 0; if (send) { e = new SendProcessorEntry (send, _width); + } else if (plugin_insert) { + e = new PluginInsertProcessorEntry (plugin_insert, _width); } else { e = new ProcessorEntry (processor, _width); } + e->set_pixel_width (get_allocation().get_width()); processor_display.add_child (e); } diff --git a/gtk2_ardour/processor_box.h b/gtk2_ardour/processor_box.h index f348569f71..a6395fc4ef 100644 --- a/gtk2_ardour/processor_box.h +++ b/gtk2_ardour/processor_box.h @@ -121,7 +121,10 @@ public: protected: + virtual void setup_visuals (); + Gtk::VBox _vbox; + Position _position; private: @@ -129,7 +132,6 @@ private: void processor_active_changed (); void processor_property_changed (const PBD::PropertyChange&); std::string name () const; - void setup_visuals (); Gtk::Frame _frame; Gtk::EventBox _event_box; @@ -139,7 +141,6 @@ private: boost::shared_ptr _processor; Width _width; Gtk::StateType _visual_state; - Position _position; PBD::ScopedConnection active_connection; PBD::ScopedConnection name_connection; }; @@ -167,6 +168,26 @@ private: static Glib::RefPtr _slider; }; +class PluginInsertProcessorEntry : public ProcessorEntry +{ +public: + PluginInsertProcessorEntry (boost::shared_ptr, Width); + +private: + void setup_visuals (); + void plugin_insert_splitting_changed (); + + /* XXX: this seems a little ridiculous just for a simple scaleable icon */ + class SplittingIcon : public Gtk::DrawingArea { + private: + bool on_expose_event (GdkEventExpose *); + }; + + boost::shared_ptr _plugin_insert; + SplittingIcon _splitting_icon; + PBD::ScopedConnection _splitting_connection; +}; + class ProcessorBox : public Gtk::HBox, public PluginInterestedObject, public ARDOUR::SessionHandlePtr { public: @@ -217,8 +238,6 @@ class ProcessorBox : public Gtk::HBox, public PluginInterestedObject, public ARD void selection_changed (); - Gtk::EventBox processor_eventbox; - Gtk::HBox processor_hpacker; Gtkmm2ext::DnDVBox processor_display; Gtk::ScrolledWindow processor_scroller; diff --git a/libs/ardour/ardour/plugin_insert.h b/libs/ardour/ardour/plugin_insert.h index 392bedb343..c52e8c2835 100644 --- a/libs/ardour/ardour/plugin_insert.h +++ b/libs/ardour/ardour/plugin_insert.h @@ -109,7 +109,13 @@ class PluginInsert : public Processor void collect_signal_for_analysis (framecnt_t nframes); + bool splitting () const { + return _splitting; + } + PBD::Signal2 AnalysisDataGathered; + /** Emitted when the return value of splitting () has changed */ + PBD::Signal0 SplittingChanged; private: /* disallow copy construction */ @@ -136,6 +142,8 @@ class PluginInsert : public Processor /** true if we are splitting one processor input to >1 plugin inputs */ bool _splitting; + void set_splitting (bool); + void automation_run (BufferSet& bufs, pframes_t nframes); void connect_and_run (BufferSet& bufs, pframes_t nframes, framecnt_t offset, bool with_auto, framepos_t now = 0); diff --git a/libs/ardour/plugin_insert.cc b/libs/ardour/plugin_insert.cc index 996d3d7dbf..43b6c8d905 100644 --- a/libs/ardour/plugin_insert.cc +++ b/libs/ardour/plugin_insert.cc @@ -569,10 +569,12 @@ bool PluginInsert::configure_io (ChanCount in, ChanCount out) { if (set_count (count_for_configuration (in, out)) == false) { + set_splitting (false); return false; } if (_plugins.front()->get_info()->n_inputs <= in) { + set_splitting (false); if (_plugins.front()->configure_io (in, out) == false) { return false; } @@ -580,8 +582,8 @@ PluginInsert::configure_io (ChanCount in, ChanCount out) /* we must be splitting a single processor input to multiple plugin inputs */ + set_splitting (true); _plugins.front()->configure_io (_plugins.front()->get_info()->n_inputs, out); - _splitting = true; } // we don't know the analysis window size, so we must work with the @@ -1154,3 +1156,14 @@ PluginInsert::realtime_handle_transport_stopped () (*i)->realtime_handle_transport_stopped (); } } + +void +PluginInsert::set_splitting (bool s) +{ + if (_splitting == s) { + return; + } + + _splitting = s; + SplittingChanged (); /* EMIT SIGNAL */ +} diff --git a/libs/gtkmm2ext/gtkmm2ext/dndvbox.h b/libs/gtkmm2ext/gtkmm2ext/dndvbox.h index c2c74e6d55..27aec2a29e 100644 --- a/libs/gtkmm2ext/gtkmm2ext/dndvbox.h +++ b/libs/gtkmm2ext/gtkmm2ext/dndvbox.h @@ -60,6 +60,8 @@ public: signal_button_release_event().connect (bind (mem_fun (*this, &DnDVBox::button_release), (T *) 0)); signal_drag_motion().connect (mem_fun (*this, &DnDVBox::drag_motion)); signal_drag_leave().connect (mem_fun (*this, &DnDVBox::drag_leave)); + + _internal_vbox.show (); drag_dest_set (_targets); signal_drag_data_received().connect (mem_fun (*this, &DnDVBox::drag_data_received)); @@ -85,7 +87,7 @@ public: _internal_vbox.pack_start (child->widget(), false, false); _children.push_back (child); - child->widget().show_all (); + child->widget().show (); } /** @return Children, sorted into the order that they are currently being displayed in the widget */