Somewhat unconvincing visual indication that plugin inserts are splitting mono inputs...
authorCarl Hetherington <carl@carlh.net>
Tue, 1 Feb 2011 01:50:49 +0000 (01:50 +0000)
committerCarl Hetherington <carl@carlh.net>
Tue, 1 Feb 2011 01:50:49 +0000 (01:50 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@8636 d708f5d6-7413-0410-9779-e7cbd77b26cf

gtk2_ardour/mixer_strip.cc
gtk2_ardour/processor_box.cc
gtk2_ardour/processor_box.h
libs/ardour/ardour/plugin_insert.h
libs/ardour/plugin_insert.cc
libs/gtkmm2ext/gtkmm2ext/dndvbox.h

index 52b84d98a183b785d5a98b105f777b93b76ec1a8..80fd6f5c38e2f5510871a28e5d7cff9e97f7a476 100644 (file)
@@ -498,7 +498,7 @@ MixerStrip::set_route (boost::shared_ptr<Route> 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<Route> 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();
index 2eaeeb83f77a78c6c5d49405618e00910b508acc..8bf4afc1cab8440a3dfd41e63c425c3071ae9b5a 100644 (file)
@@ -95,10 +95,10 @@ RefPtr<Action> ProcessorBox::edit_action;
 Glib::RefPtr<Gdk::Pixbuf> SendProcessorEntry::_slider;
 
 ProcessorEntry::ProcessorEntry (boost::shared_ptr<Processor> 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<Processor> 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<ARDOUR::PluginInsert> 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<PluginSelector*()> get_plugin_selector,
                            RouteRedirectSelection& rsel, MixerStrip* parent, bool owner_is_mixer)
        : _parent_strip (parent)
@@ -388,6 +471,9 @@ ProcessorBox::ProcessorBox (ARDOUR::Session* sess, boost::function<PluginSelecto
        processor_display.DropFromAnotherBox.connect (sigc::mem_fun (*this, &ProcessorBox::object_drop));
        processor_display.SelectionChanged.connect (sigc::mem_fun (*this, &ProcessorBox::selection_changed));
 
+       processor_scroller.show ();
+       processor_display.show ();
+
        if (parent) {
                parent->DeliveryChanged.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<ProcessorWindowProxy*>::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<Processor> p)
        }
 
        boost::shared_ptr<Send> send = boost::dynamic_pointer_cast<Send> (processor);
+       boost::shared_ptr<PluginInsert> plugin_insert = boost::dynamic_pointer_cast<PluginInsert> (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);
 }
index f348569f71164072eb3e6150fe4a0104f42334d1..a6395fc4ef4830f910257e77600341854d7a53f9 100644 (file)
@@ -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<ARDOUR::Processor> _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<Gdk::Pixbuf> _slider;
 };
 
+class PluginInsertProcessorEntry : public ProcessorEntry
+{
+public:
+       PluginInsertProcessorEntry (boost::shared_ptr<ARDOUR::PluginInsert>, 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<ARDOUR::PluginInsert> _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<ProcessorEntry> processor_display;
        Gtk::ScrolledWindow    processor_scroller;
 
index 392bedb3431c5cf6b056cfb017d4b0884053b4de..c52e8c2835dcdb8932fabf379313a1ab401aa36d 100644 (file)
@@ -109,7 +109,13 @@ class PluginInsert : public Processor
 
        void collect_signal_for_analysis (framecnt_t nframes);
 
+       bool splitting () const {
+               return _splitting;
+       }
+
        PBD::Signal2<void,BufferSet*, BufferSet*> AnalysisDataGathered;
+       /** Emitted when the return value of splitting () has changed */
+       PBD::Signal0<void> 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);
 
index 996d3d7dbfbf905d935af7faa4cd3eb1fe480641..43b6c8d9057fbd3cf76b4e77c888e3318fa97cb0 100644 (file)
@@ -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 */
+}
index c2c74e6d5550901792b7bbff8ba07df97fbbbe54..27aec2a29e55f1b714bf9eb928857136657202d2 100644 (file)
@@ -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 */