First cut at mouseovers for the port matrix.
authorCarl Hetherington <carl@carlh.net>
Tue, 27 Jan 2009 04:21:13 +0000 (04:21 +0000)
committerCarl Hetherington <carl@carlh.net>
Tue, 27 Jan 2009 04:21:13 +0000 (04:21 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@4446 d708f5d6-7413-0410-9779-e7cbd77b26cf

14 files changed:
gtk2_ardour/bundle_manager.cc
gtk2_ardour/io_selector.cc
gtk2_ardour/port_group.cc
gtk2_ardour/port_group.h
gtk2_ardour/port_matrix_body.cc
gtk2_ardour/port_matrix_body.h
gtk2_ardour/port_matrix_column_labels.cc
gtk2_ardour/port_matrix_column_labels.h
gtk2_ardour/port_matrix_component.h
gtk2_ardour/port_matrix_grid.cc
gtk2_ardour/port_matrix_grid.h
gtk2_ardour/port_matrix_row_labels.cc
gtk2_ardour/port_matrix_row_labels.h
gtk2_ardour/port_matrix_types.h [new file with mode: 0644]

index 04bf240f7ce1af0daa8a79f0c5913c5784168100..0f4bdb3c754a567fb435d4ecafaa4d396c1e534e 100644 (file)
@@ -36,7 +36,7 @@ BundleEditorMatrix::BundleEditorMatrix (
        : PortMatrix (session, bundle->type(), bundle->ports_are_inputs())
 {
        _port_group = new PortGroup ("", true);
-       _port_group->bundles.push_back (bundle);
+       _port_group->add_bundle (bundle);
        _row_ports.push_back (_port_group);
 }
 
@@ -93,14 +93,14 @@ BundleEditorMatrix::add_channel (boost::shared_ptr<ARDOUR::Bundle> b)
                return;
        }
 
-       _port_group->bundles.front()->add_channel (d.get_name());
+       _port_group->only_bundle()->add_channel (d.get_name());
        setup ();
 }
 
 void
 BundleEditorMatrix::remove_channel (boost::shared_ptr<ARDOUR::Bundle> b, uint32_t c)
 {
-       _port_group->bundles.front()->remove_channel (c);
+       _port_group->only_bundle()->remove_channel (c);
        setup ();
 }
 
index cb1a07ce14a64b0f6b1f5f01847a9e325a9176d6..b472c8eb71b70fe91a677c6cd0b0498a60227bf3 100644 (file)
@@ -63,9 +63,9 @@ IOSelector::~IOSelector ()
 void
 IOSelector::setup ()
 {
-       _port_group->bundles.clear ();
-       _port_group->bundles.push_back (boost::shared_ptr<ARDOUR::Bundle> (new ARDOUR::Bundle));
-       _port_group->bundles.front()->set_name (_io->name());
+       _port_group->clear ();
+       _port_group->add_bundle (boost::shared_ptr<ARDOUR::Bundle> (new ARDOUR::Bundle));
+       _port_group->only_bundle()->set_name (_io->name());
 
        if (offering_input ()) {
                const PortSet& ps (_io->outputs());
@@ -74,8 +74,8 @@ IOSelector::setup ()
                for (PortSet::const_iterator i = ps.begin(); i != ps.end(); ++i) {
                        char buf[32];
                        snprintf (buf, sizeof(buf), _("out %d"), j + 1);
-                       _port_group->bundles.front()->add_channel (buf);
-                       _port_group->bundles.front()->add_port_to_channel (j, _session.engine().make_port_name_non_relative (i->name()));
+                       _port_group->only_bundle()->add_channel (buf);
+                       _port_group->only_bundle()->add_port_to_channel (j, _session.engine().make_port_name_non_relative (i->name()));
                        ++j;
                }
                
@@ -87,8 +87,8 @@ IOSelector::setup ()
                for (PortSet::const_iterator i = ps.begin(); i != ps.end(); ++i) {
                        char buf[32];
                        snprintf (buf, sizeof(buf), _("in %d"), j + 1);
-                       _port_group->bundles.front()->add_channel (buf);
-                       _port_group->bundles.front()->add_port_to_channel (j, _session.engine().make_port_name_non_relative (i->name()));
+                       _port_group->only_bundle()->add_channel (buf);
+                       _port_group->only_bundle()->add_port_to_channel (j, _session.engine().make_port_name_non_relative (i->name()));
                        ++j;
                }
 
index 086e0b75d982478eced70fa21f8036ba776679ba..2544268586d3e769c712011d6fd4b92782cea106 100644 (file)
@@ -38,7 +38,8 @@ using namespace Gtk;
 void
 PortGroup::add_bundle (boost::shared_ptr<ARDOUR::Bundle> b)
 {
-       bundles.push_back (b);
+       assert (b.get());
+       _bundles.push_back (b);
 }
 
 /** Add a port to a group.
@@ -53,14 +54,14 @@ PortGroup::add_port (std::string const &p)
 void
 PortGroup::clear ()
 {
-       bundles.clear ();
+       _bundles.clear ();
        ports.clear ();
 }
 
 bool
 PortGroup::has_port (std::string const& p) const
 {
-       for (ARDOUR::BundleList::const_iterator i = bundles.begin(); i != bundles.end(); ++i) {
+       for (ARDOUR::BundleList::const_iterator i = _bundles.begin(); i != _bundles.end(); ++i) {
                if ((*i)->offers_port_alone (p)) {
                        return true;
                }
@@ -74,6 +75,13 @@ PortGroup::has_port (std::string const& p) const
 
        return false;
 }
+
+boost::shared_ptr<ARDOUR::Bundle>
+PortGroup::only_bundle ()
+{
+       assert (_bundles.size() == 1);
+       return _bundles.front();
+}
        
 
 /** PortGroupUI constructor.
@@ -116,7 +124,7 @@ PortGroupUI::setup_visibility_checkbutton ()
  */
 
 PortGroupList::PortGroupList (ARDOUR::DataType type, bool offer_inputs)
-       : _type (type), _offer_inputs (offer_inputs),
+       : _type (type), _offer_inputs (offer_inputs), _bundles_dirty (true),
          _buss (_("Bus"), true),
          _track (_("Track"), true),
          _system (_("System"), true),
@@ -185,7 +193,7 @@ PortGroupList::gather (ARDOUR::Session& session)
        boost::shared_ptr<ARDOUR::BundleList> b = session.bundles ();
        for (ARDOUR::BundleList::iterator i = b->begin(); i != b->end(); ++i) {
                if ((*i)->ports_are_inputs() == _offer_inputs && (*i)->type() == _type) {
-                       _system.bundles.push_back (*i);
+                       _system.add_bundle (*i);
                }
        }
 
@@ -232,6 +240,8 @@ PortGroupList::gather (ARDOUR::Session& session)
                        (*i)->VisibilityChanged.connect (sigc::mem_fun (*this, &PortGroupList::visibility_changed))
                        );
        }
+
+       _bundles_dirty = true;
 }
 
 bool
@@ -245,24 +255,26 @@ void
 PortGroupList::set_type (ARDOUR::DataType t)
 {
        _type = t;
+       _bundles_dirty = true;
 }
 
 void
 PortGroupList::set_offer_inputs (bool i)
 {
        _offer_inputs = i;
+       _bundles_dirty = true;
 }
 
-ARDOUR::BundleList
-PortGroupList::bundles () const
+void
+PortGroupList::update_bundles () const
 {
-       ARDOUR::BundleList bundles;
+       _bundles.clear ();
                
        for (const_iterator i = begin (); i != end (); ++i) {
                if ((*i)->visible()) {
                        
-                       std::copy ((*i)->bundles.begin(), (*i)->bundles.end(), std::back_inserter (bundles));
-                       
+                       std::copy ((*i)->bundles().begin(), (*i)->bundles().end(), std::back_inserter (_bundles));
+
                        /* make a bundle for the ports, if there are any */
                        if (!(*i)->ports.empty()) {
 
@@ -279,12 +291,12 @@ PortGroupList::bundles () const
                                        b->set_port (j, p);
                                }
                                        
-                               bundles.push_back (b);
+                               _bundles.push_back (b);
                        }
                }
        }
 
-       return bundles;
+       _bundles_dirty = false;
 }
 
 std::string
@@ -359,4 +371,15 @@ PortGroupList::clear_list ()
        }
 
        _visibility_connections.clear ();
+       _bundles_dirty = true;
+}
+
+ARDOUR::BundleList const &
+PortGroupList::bundles () const
+{
+       if (_bundles_dirty) {
+               update_bundles ();
+       }
+
+       return _bundles;
 }
index 17e9842f93b2c6f9b9076035f5583eddada696a2..d6008b61ba4f8980c6d74bc5dd5cbd8bca908e4e 100644 (file)
@@ -50,12 +50,17 @@ public:
                : name (n), _visible (v) {}
 
        void add_bundle (boost::shared_ptr<ARDOUR::Bundle>);
+       boost::shared_ptr<ARDOUR::Bundle> only_bundle ();
        void add_port (std::string const &);
        void clear ();
 
        std::string name; ///< name for the group
-       ARDOUR::BundleList bundles;
        std::vector<std::string> ports;
+
+       ARDOUR::BundleList const & bundles () const {
+               return _bundles;
+       }
+       
        bool visible () const {
                return _visible;
        }
@@ -70,6 +75,7 @@ public:
        sigc::signal<void> VisibilityChanged;
 
 private:       
+       ARDOUR::BundleList _bundles;
        bool _visible; ///< true if the group is visible in the UI
 };
 
@@ -101,7 +107,7 @@ class PortGroupList : public std::list<PortGroup*>, public sigc::trackable
        void gather (ARDOUR::Session &);
        void set_type (ARDOUR::DataType);
        void set_offer_inputs (bool);
-       ARDOUR::BundleList bundles () const;
+       ARDOUR::BundleList const & bundles () const;
        void take_visibility_from (PortGroupList const &);
        void clear_list ();
 
@@ -111,9 +117,12 @@ class PortGroupList : public std::list<PortGroup*>, public sigc::trackable
        bool port_has_prefix (std::string const &, std::string const &) const;
        std::string common_prefix (std::vector<std::string> const &) const;
        void visibility_changed ();
+       void update_bundles () const;
        
        ARDOUR::DataType _type;
        bool _offer_inputs;
+       mutable ARDOUR::BundleList _bundles;
+       mutable bool _bundles_dirty;
 
        PortGroup _buss;
        PortGroup _track;
index 3531712a5643c600fa72f2443537c4bfa109e5c8..d30fd58c6af6b375b89537c13b78f36cb9fcd031 100644 (file)
@@ -31,10 +31,12 @@ PortMatrixBody::PortMatrixBody (PortMatrix* p, Arrangement a)
          _arrangement (a),
          _xoffset (0),
          _yoffset (0),
+         _pointer_inside (false),
          _column_ports (_port_matrix->type(), _port_matrix->offering_input()),
          _row_ports (_port_matrix->type(), !_port_matrix->offering_input())
 {
        modify_bg (Gtk::STATE_NORMAL, Gdk::Color ("#00000"));
+       add_events (Gdk::ENTER_NOTIFY_MASK | Gdk::LEAVE_NOTIFY_MASK | Gdk::POINTER_MOTION_MASK);
 }
 
 
@@ -47,15 +49,15 @@ PortMatrixBody::on_expose_event (GdkEventExpose* event)
 
        bool intersects;
        Gdk::Rectangle r = exposure;
-       r.intersect (_column_labels_rect, intersects);
+       r.intersect (_column_labels.parent_rectangle(), intersects);
 
        if (intersects) {
                gdk_draw_drawable (
                        get_window()->gobj(),
                        get_style()->get_fg_gc (Gtk::STATE_NORMAL)->gobj(),
                        _column_labels.get_pixmap (get_window()->gobj()),
-                       r.get_x() - _column_labels_rect.get_x() + _xoffset,
-                       r.get_y() - _column_labels_rect.get_y(),
+                       _column_labels.parent_to_component_x (r.get_x()),
+                       _column_labels.parent_to_component_y (r.get_y()),
                        r.get_x(),
                        r.get_y(),
                        r.get_width(),
@@ -64,15 +66,15 @@ PortMatrixBody::on_expose_event (GdkEventExpose* event)
        }
 
        r = exposure;
-       r.intersect (_row_labels_rect, intersects);
+       r.intersect (_row_labels.parent_rectangle(), intersects);
 
        if (intersects) {
                gdk_draw_drawable (
                        get_window()->gobj(),
                        get_style()->get_fg_gc (Gtk::STATE_NORMAL)->gobj(),
                        _row_labels.get_pixmap (get_window()->gobj()),
-                       r.get_x() - _row_labels_rect.get_x(),
-                       r.get_y() - _row_labels_rect.get_y() + _yoffset,
+                       _row_labels.parent_to_component_x (r.get_x()),
+                       _row_labels.parent_to_component_y (r.get_y()),
                        r.get_x(),
                        r.get_y(),
                        r.get_width(),
@@ -81,15 +83,15 @@ PortMatrixBody::on_expose_event (GdkEventExpose* event)
        }
 
        r = exposure;
-       r.intersect (_grid_rect, intersects);
+       r.intersect (_grid.parent_rectangle(), intersects);
 
        if (intersects) {
                gdk_draw_drawable (
                        get_window()->gobj(),
                        get_style()->get_fg_gc (Gtk::STATE_NORMAL)->gobj(),
                        _grid.get_pixmap (get_window()->gobj()),
-                       r.get_x() - _grid_rect.get_x() + _xoffset,
-                       r.get_y() - _grid_rect.get_y() + _yoffset,
+                       _grid.parent_to_component_x (r.get_x()),
+                       _grid.parent_to_component_y (r.get_y()),
                        r.get_x(),
                        r.get_y(),
                        r.get_width(),
@@ -97,6 +99,12 @@ PortMatrixBody::on_expose_event (GdkEventExpose* event)
                        );
        }
 
+       cairo_t* cr = gdk_cairo_create (get_window()->gobj());
+       _grid.draw_extra (cr);
+       _row_labels.draw_extra (cr);
+       _column_labels.draw_extra (cr);
+       cairo_destroy (cr);
+
        return true;
 }
 
@@ -132,18 +140,22 @@ PortMatrixBody::compute_rectangles ()
        std::pair<uint32_t, uint32_t> const row = _row_labels.dimensions ();
        std::pair<uint32_t, uint32_t> const grid = _grid.dimensions ();
 
+       Gdk::Rectangle col_rect;
+       Gdk::Rectangle row_rect;
+       Gdk::Rectangle grid_rect;
+
        if (_arrangement == TOP_AND_RIGHT) {
 
                /* build from top left */
 
-               _column_labels_rect.set_x (0);
-               _column_labels_rect.set_y (0);
-               _grid_rect.set_x (0);
+               col_rect.set_x (0);
+               col_rect.set_y (0);
+               grid_rect.set_x (0);
 
                if (_alloc_width > col.first) {
-                       _column_labels_rect.set_width (col.first);
+                       col_rect.set_width (col.first);
                } else {
-                       _column_labels_rect.set_width (_alloc_width);
+                       col_rect.set_width (_alloc_width);
                }
 
                /* move down to y division */
@@ -155,11 +167,11 @@ PortMatrixBody::compute_rectangles ()
                        y = _alloc_height;
                }
 
-               _column_labels_rect.set_height (y);
-               _row_labels_rect.set_y (y);
-               _row_labels_rect.set_height (_alloc_height - y);
-               _grid_rect.set_y (y);
-               _grid_rect.set_height (_alloc_height - y);
+               col_rect.set_height (y);
+               row_rect.set_y (y);
+               row_rect.set_height (_alloc_height - y);
+               grid_rect.set_y (y);
+               grid_rect.set_height (_alloc_height - y);
 
                /* move right to x division */
 
@@ -170,9 +182,9 @@ PortMatrixBody::compute_rectangles ()
                        x = _alloc_width - row.first;
                }
 
-               _grid_rect.set_width (x);
-               _row_labels_rect.set_x (x);
-               _row_labels_rect.set_width (_alloc_width - x);
+               grid_rect.set_width (x);
+               row_rect.set_x (x);
+               row_rect.set_width (_alloc_width - x);
                        
 
        } else if (_arrangement == BOTTOM_AND_LEFT) {
@@ -188,13 +200,13 @@ PortMatrixBody::compute_rectangles ()
                        x = _alloc_width - row.first;
                }
 
-               _grid_rect.set_x (_alloc_width - x);
-               _grid_rect.set_width (x);
-               _column_labels_rect.set_width (col.first - grid.first + x);
-               _column_labels_rect.set_x (_alloc_width - _column_labels_rect.get_width());
+               grid_rect.set_x (_alloc_width - x);
+               grid_rect.set_width (x);
+               col_rect.set_width (col.first - grid.first + x);
+               col_rect.set_x (_alloc_width - col_rect.get_width());
 
-               _row_labels_rect.set_width (std::min (_alloc_width - x, row.first));
-               _row_labels_rect.set_x (_alloc_width - x - _row_labels_rect.get_width());
+               row_rect.set_width (std::min (_alloc_width - x, row.first));
+               row_rect.set_x (_alloc_width - x - row_rect.get_width());
 
                /* move up to the y division */
                
@@ -205,16 +217,19 @@ PortMatrixBody::compute_rectangles ()
                        y = _alloc_height;
                }
 
-               _column_labels_rect.set_y (_alloc_height - y);
-               _column_labels_rect.set_height (y);
+               col_rect.set_y (_alloc_height - y);
+               col_rect.set_height (y);
 
-               _grid_rect.set_height (std::min (grid.second, _alloc_height - y));
-               _grid_rect.set_y (_alloc_height - y - _grid_rect.get_height());
-
-               _row_labels_rect.set_height (_grid_rect.get_height());
-               _row_labels_rect.set_y (_grid_rect.get_y());
+               grid_rect.set_height (std::min (grid.second, _alloc_height - y));
+               grid_rect.set_y (_alloc_height - y - grid_rect.get_height());
 
+               row_rect.set_height (grid_rect.get_height());
+               row_rect.set_y (grid_rect.get_y());
        }
+
+       _row_labels.set_parent_rectangle (row_rect);
+       _column_labels.set_parent_rectangle (col_rect);
+       _grid.set_parent_rectangle (grid_rect);
 }
 
 void
@@ -262,7 +277,7 @@ PortMatrixBody::full_scroll_width ()
 uint32_t
 PortMatrixBody::alloc_scroll_width ()
 {
-       return _grid_rect.get_width();
+       return _grid.parent_rectangle().get_width();
 }
 
 uint32_t
@@ -274,7 +289,7 @@ PortMatrixBody::full_scroll_height ()
 uint32_t
 PortMatrixBody::alloc_scroll_height ()
 {
-       return _grid_rect.get_height();
+       return _grid.parent_rectangle().get_height();
 }
 
 void
@@ -294,19 +309,19 @@ PortMatrixBody::set_yoffset (uint32_t yo)
 bool
 PortMatrixBody::on_button_press_event (GdkEventButton* ev)
 {
-       if (Gdk::Region (_grid_rect).point_in (ev->x, ev->y)) {
+       if (Gdk::Region (_grid.parent_rectangle()).point_in (ev->x, ev->y)) {
 
                _grid.button_press (
-                       ev->x - _grid_rect.get_x() + _xoffset,
-                       ev->y - _grid_rect.get_y() + _yoffset,
+                       _grid.parent_to_component_x (ev->x),
+                       _grid.parent_to_component_y (ev->y),
                        ev->button
                        );
 
-       } else if (Gdk::Region (_row_labels_rect).point_in (ev->x, ev->y)) {
+       } else if (Gdk::Region (_row_labels.parent_rectangle()).point_in (ev->x, ev->y)) {
 
                _row_labels.button_press (
-                       ev->x - _row_labels_rect.get_x(),
-                       ev->y - _row_labels_rect.get_y() + _yoffset,
+                       _row_labels.parent_to_component_x (ev->x),
+                       _row_labels.parent_to_component_y (ev->y),
                        ev->button, ev->time
                        );
        
@@ -339,3 +354,43 @@ PortMatrixBody::rebuild_and_draw_row_labels ()
        _row_labels.require_rebuild ();
        queue_draw ();
 }
+
+bool
+PortMatrixBody::on_enter_notify_event (GdkEventCrossing* ev)
+{
+       if (ev->type == GDK_ENTER_NOTIFY) {
+               _pointer_inside = true;
+       } else if (ev->type == GDK_LEAVE_NOTIFY) {
+               _pointer_inside = false;
+       }
+
+       return true;
+}
+
+bool
+PortMatrixBody::on_motion_notify_event (GdkEventMotion* ev)
+{
+       if (_pointer_inside && Gdk::Region (_grid.parent_rectangle()).point_in (ev->x, ev->y)) {
+               _grid.mouseover_event (
+                       _grid.parent_to_component_x (ev->x),
+                       _grid.parent_to_component_y (ev->y)
+                       );
+       }
+
+       return true;
+}
+
+void
+PortMatrixBody::set_mouseover (PortMatrixNode const & n)
+{
+       if (n == _mouseover) {
+               return;
+       }
+
+       PortMatrixNode old = _mouseover;
+       _mouseover = n;
+       
+       _grid.mouseover_changed (old);
+       _row_labels.mouseover_changed (old);
+       _column_labels.mouseover_changed (old);
+}
index c9fd8bdb653b8a3677bf0afa860a43fd4b5c5a7f..2a68a251bf6221105cf104953fe5478fa3541001 100644 (file)
@@ -24,6 +24,7 @@
 #include "port_matrix_row_labels.h"
 #include "port_matrix_grid.h"
 #include "port_group.h"
+#include "port_matrix_types.h"
 
 class PortMatrix;
 
@@ -58,21 +59,35 @@ public:
        uint32_t full_scroll_height ();
        uint32_t alloc_scroll_height ();
 
+       uint32_t xoffset () const {
+               return _xoffset;
+       }
        void set_xoffset (uint32_t);
+       uint32_t yoffset () const {
+               return _yoffset;
+       }
        void set_yoffset (uint32_t);
 
        void rebuild_and_draw_grid ();
-
+       
+       void set_mouseover (PortMatrixNode const &);
+       PortMatrixNode mouseover () const {
+               return _mouseover;
+       }
+       
 protected:
        bool on_expose_event (GdkEventExpose *);
        void on_size_request (Gtk::Requisition *);
        void on_size_allocate (Gtk::Allocation &);
        bool on_button_press_event (GdkEventButton *);
-
+       bool on_enter_notify_event (GdkEventCrossing *);
+       bool on_motion_notify_event (GdkEventMotion *);
+       
 private:
        void compute_rectangles ();
        void rebuild_and_draw_column_labels ();
        void rebuild_and_draw_row_labels ();
+       void update_bundles ();
        
        PortMatrix* _port_matrix;
        PortMatrixColumnLabels _column_labels;
@@ -87,12 +102,15 @@ private:
        Gdk::Rectangle _grid_rect;
        uint32_t _xoffset;
        uint32_t _yoffset;
+       bool _pointer_inside;
 
        /// bundles to offer for columns
        PortGroupList _column_ports;
        /// bundles to offer for rows
        PortGroupList _row_ports;
 
+       PortMatrixNode _mouseover;
+
        std::list<sigc::connection> _bundle_connections;
 };
 
index 3ef501d89bc11c601f67e1d66d1e9f23f81b9bda..bd6a14e6fa5a5d2afc97ebc21bed312a7907daac 100644 (file)
@@ -133,13 +133,13 @@ PortMatrixColumnLabels::render (cairo_t* cr)
        int g = 0;
        for (PortGroupList::const_iterator i = _body->column_ports().begin(); i != _body->column_ports().end(); ++i) {
 
-               if (!(*i)->visible() || ((*i)->bundles.empty() && (*i)->ports.empty()) ) {
+               if (!(*i)->visible() || ((*i)->bundles().empty() && (*i)->ports.empty()) ) {
                        continue;
                }
 
                /* compute width of this group */
                uint32_t w = 0;
-               for (ARDOUR::BundleList::const_iterator j = (*i)->bundles.begin(); j != (*i)->bundles.end(); ++j) {
+               for (ARDOUR::BundleList::const_iterator j = (*i)->bundles().begin(); j != (*i)->bundles().end(); ++j) {
                        w += (*j)->nchannels() * column_width();
                }
                w += (*i)->ports.size() * column_width();
@@ -236,71 +236,183 @@ PortMatrixColumnLabels::render (cairo_t* cr)
                
                for (uint32_t j = 0; j < (*i)->nchannels(); ++j) {
 
-                       double const lc = _longest_channel_name + name_pad();
-                       double const w = column_width();
-                       double const ph = _height - _highest_group_name - 2 * name_pad();
+                       render_port_name (cr, get_a_bundle_colour (i - c.begin()), x, 0, PortMatrixBundleChannel (*i, j));
+                       x += column_width();
+               }
+       }
+}
 
-                       if (_location == BOTTOM) {
-
-                               double x_ = x + ph / tan (angle()) + w;
-                               double const ix = x_;
-                               double y_ = 0;
-                               cairo_move_to (cr, x_, y_);
-                               x_ -= w;
-                               cairo_line_to (cr, x_, y_);
-                               x_ -= lc * cos (angle());
-                               y_ += lc * sin (angle());
-                               cairo_line_to (cr, x_, y_);
-                               x_ += w * pow (sin (angle()), 2);
-                               y_ += w * sin (angle()) * cos (angle());
-                               cairo_line_to (cr, x_, y_);
-                               cairo_line_to (cr, ix, 0);
-
-                       } else if (_location == TOP) {
-
-                               double x_ = x;
-                               double y_ = _height;
-                               cairo_move_to (cr, x_, y_);
-                               x_ += w;
-                               cairo_line_to (cr, x_, y_);
-                               x_ += lc * cos (angle());
-                               y_ -= lc * sin (angle());
-                               cairo_line_to (cr, x_, y_);
-                               x_ -= column_width() * pow (sin (angle()), 2);
-                               y_ -= column_width() * sin (angle()) * cos (angle());
-                               cairo_line_to (cr, x_, y_);
-                               cairo_line_to (cr, x, _height);
+double
+PortMatrixColumnLabels::component_to_parent_x (double x) const
+{
+       return x - _body->xoffset() + _parent_rectangle.get_x();
+}
 
-                       }
+double
+PortMatrixColumnLabels::parent_to_component_x (double x) const
+{
+       return x + _body->xoffset() - _parent_rectangle.get_x();
+}
 
-                       Gdk::Color colour = get_a_bundle_colour (i - c.begin());
-                       set_source_rgb (cr, colour);
-                       cairo_fill_preserve (cr);
-                       set_source_rgb (cr, background_colour());
-                       cairo_set_line_width (cr, label_border_width());
-                       cairo_stroke (cr);
+double
+PortMatrixColumnLabels::component_to_parent_y (double y) const
+{
+       return y + _parent_rectangle.get_y();
+}
 
-                       set_source_rgb (cr, text_colour());
+double
+PortMatrixColumnLabels::parent_to_component_y (double y) const
+{
+       return y - _parent_rectangle.get_y();
+}
 
-                       if (_location == TOP) {
-                               cairo_move_to (cr, x + basic_text_x_pos(j), _height - name_pad() * sin (angle()));
-                       } else if (_location == BOTTOM) {
-                               double const rl = 3 * name_pad() + _longest_bundle_name;
-                               cairo_move_to (cr, x + basic_text_x_pos(j) + rl * cos (angle ()), ph - rl * sin (angle()));
-                       }
-                       
-                       cairo_save (cr);
-                       cairo_rotate (cr, -angle());
+void
+PortMatrixColumnLabels::mouseover_changed (PortMatrixNode const& old)
+{
+       queue_draw_for (old);
+       queue_draw_for (_body->mouseover());
+}
 
-                       cairo_show_text (
-                               cr,
-                               (*i)->channel_name(j).c_str()
+void
+PortMatrixColumnLabels::draw_extra (cairo_t* cr)
+{
+       if (_body->mouseover().column.bundle) {
+               render_port_name (
+                       cr,
+                       mouseover_port_colour (),
+                       component_to_parent_x (channel_x (_body->mouseover().column)),
+                       component_to_parent_y (0),
+                       _body->mouseover().column
+                       );
+       }
+
+}
+
+void
+PortMatrixColumnLabels::render_port_name (cairo_t* cr, Gdk::Color colour, double x, double y, PortMatrixBundleChannel const &bc)
+{
+       double const lc = _longest_channel_name + name_pad();
+       double const w = column_width();
+       double const ph = _height - _highest_group_name - 2 * name_pad();
+
+       if (_location == BOTTOM) {
+
+               double x_ = x + ph / tan (angle()) + w;
+               double const ix = x_;
+               double y_ = y;
+               cairo_move_to (cr, x_, y_);
+               x_ -= w;
+               cairo_line_to (cr, x_, y_);
+               x_ -= lc * cos (angle());
+               y_ += lc * sin (angle());
+               cairo_line_to (cr, x_, y_);
+               x_ += w * pow (sin (angle()), 2);
+               y_ += w * sin (angle()) * cos (angle());
+               cairo_line_to (cr, x_, y_);
+               cairo_line_to (cr, ix, y);
+               
+       } else if (_location == TOP) {
+               
+               double x_ = x;
+               double y_ = y + _height;
+               cairo_move_to (cr, x_, y_);
+               x_ += w;
+               cairo_line_to (cr, x_, y_);
+               x_ += lc * cos (angle());
+               y_ -= lc * sin (angle());
+               cairo_line_to (cr, x_, y_);
+               x_ -= column_width() * pow (sin (angle()), 2);
+               y_ -= column_width() * sin (angle()) * cos (angle());
+               cairo_line_to (cr, x_, y_);
+               cairo_line_to (cr, x, y + _height);
+               
+       }
+       
+       set_source_rgb (cr, colour);
+       cairo_fill_preserve (cr);
+       set_source_rgb (cr, background_colour());
+       cairo_set_line_width (cr, label_border_width());
+       cairo_stroke (cr);
+       
+       set_source_rgb (cr, text_colour());
+       
+       if (_location == TOP) {
+
+               cairo_move_to (
+                       cr,
+                       x + basic_text_x_pos(bc.channel),
+                       y + _height - name_pad() * sin (angle())
+                       );
+               
+       } else if (_location == BOTTOM) {
+
+               double const rl = 3 * name_pad() + _longest_bundle_name;
+               cairo_move_to (
+                       cr,
+                       x + basic_text_x_pos(bc.channel) + rl * cos (angle ()),
+                       y + ph - rl * sin (angle())
+                       );
+       }
+       
+       cairo_save (cr);
+       cairo_rotate (cr, -angle());
+       
+       cairo_show_text (
+               cr,
+               bc.bundle->channel_name(bc.channel).c_str()
+               );
+       
+       cairo_restore (cr);
+}
+
+double
+PortMatrixColumnLabels::channel_x (PortMatrixBundleChannel const &bc) const
+{
+       double x = 0;
+
+       ARDOUR::BundleList::const_iterator i = _body->column_ports().bundles().begin();
+       while (i != _body->column_ports().bundles().end() && *i != bc.bundle) {
+               x += column_width() * (*i)->nchannels();
+               ++i;
+       }
+
+       x += column_width() * bc.channel;
+
+       return x;
+}
+
+void
+PortMatrixColumnLabels::queue_draw_for (PortMatrixNode const& n)
+{
+       if (n.column.bundle) {
+               
+               double const x = channel_x (n.column);
+               double const lc = _longest_channel_name + name_pad();
+               double const h = lc * sin (angle ()) + column_width() * sin (angle()) * cos (angle());
+               if (_location == TOP) {
+
+                       _body->queue_draw_area (
+                               component_to_parent_x (x),
+                               component_to_parent_y (_height - h),
+                               column_width() + lc * cos (angle()),
+                               h
+                               );
+                       
+               } else if (_location == BOTTOM) {
+                       
+                       double const ph = _height - _highest_group_name - 2 * name_pad();
+                       double const w = column_width() + lc * cos (angle());
+                       double const x_ = x + ph / tan (angle()) - lc * cos (angle());
+                       
+                       _body->queue_draw_area (
+                               component_to_parent_x (x_),
+                               component_to_parent_y (0),
+                               column_width() + lc * cos (angle()),
+                               h
                                );
                        
-                       cairo_restore (cr);
-
-                       x += column_width();
                }
+                       
+                               
        }
 }
-
index 5bdd7a29303b45e22d90b94259589d0c0509808c..213b760a25a9751eff422420b14f1c519610eea3 100644 (file)
 #include <boost/shared_ptr.hpp>
 #include "port_matrix_component.h"
 
-class PortMatrixBody;
-
 namespace ARDOUR {
        class Bundle;
 }
 
+class PortMatrixNode;
+class PortMatrixBundleChannel;
+
 /** The column labels part of the port matrix */
 class PortMatrixColumnLabels : public PortMatrixComponent
 {
@@ -41,10 +42,20 @@ public:
        
        PortMatrixColumnLabels (PortMatrixBody *, Location);
 
+       double component_to_parent_x (double x) const;
+       double parent_to_component_x (double x) const;
+       double component_to_parent_y (double y) const;
+       double parent_to_component_y (double y) const;
+       void mouseover_changed (PortMatrixNode const &);
+       void draw_extra (cairo_t *);
+
 private:
        void render (cairo_t *);
        void compute_dimensions ();
        double basic_text_x_pos (int) const;
+       void render_port_name (cairo_t *, Gdk::Color, double, double, PortMatrixBundleChannel const &);
+       double channel_x (PortMatrixBundleChannel const &) const;
+       void queue_draw_for (PortMatrixNode const &);
 
        std::vector<boost::shared_ptr<ARDOUR::Bundle> > _bundles;
        double _longest_bundle_name;
index cc0f0826954188f38e86ba69d6d083adc39269a8..7531e44bddd81cf06ed8ea488bdd00139a669a48 100644 (file)
@@ -23,6 +23,7 @@
 #include <gtkmm/eventbox.h>
 
 class PortMatrixBody;
+class PortMatrixNode;
 
 /** One component of the PortMatrix.  This is a cairo-rendered
  *  Pixmap.
@@ -33,6 +34,13 @@ public:
        PortMatrixComponent (PortMatrixBody *);
        virtual ~PortMatrixComponent ();
 
+       virtual double component_to_parent_x (double x) const = 0;
+       virtual double parent_to_component_x (double x) const = 0;
+       virtual double component_to_parent_y (double y) const = 0;
+       virtual double parent_to_component_y (double y) const = 0;
+       virtual void mouseover_changed (PortMatrixNode const &) = 0;
+       virtual void draw_extra (cairo_t *) = 0;
+
        void setup ();
        GdkPixmap* get_pixmap (GdkDrawable *);
        std::pair<uint32_t, uint32_t> dimensions ();
@@ -46,6 +54,14 @@ public:
                _render_required = true;
        }
 
+       void set_parent_rectangle (Gdk::Rectangle const & r) {
+               _parent_rectangle = r;
+       }
+
+       Gdk::Rectangle parent_rectangle () const {
+               return _parent_rectangle;
+       }
+
        /** @return width of columns in the grid */
        static uint32_t column_width () {
                return 32;
@@ -83,6 +99,10 @@ protected:
                return 8;
        }
 
+       static uint32_t mouseover_line_width () {
+               return 4;
+       }
+
        /** @return angle of column labels, in radians */
        static double angle () {
                return M_PI / 4;
@@ -115,6 +135,16 @@ protected:
                return Gdk::Color ("#cccccc");
        }
 
+       /** @return colour to paint mouseover lines */
+       static Gdk::Color mouseover_line_colour () {
+               return Gdk::Color ("#ff0000");
+       }
+
+       /** @return colour to paint mouseover lines */
+       static Gdk::Color mouseover_port_colour () {
+               return Gdk::Color ("#777777");
+       }
+
        /* XXX */
        static Gdk::Color get_a_bundle_colour (int x) {
                if ((x % 2) == 0) {
@@ -147,6 +177,7 @@ protected:
        PortMatrixBody* _body; ///< the PortMatrixBody that we're in
        uint32_t _width; ///< full width of the contents
        uint32_t _height; ///< full height of the contents
+       Gdk::Rectangle _parent_rectangle;
 
 private:       
        GdkPixmap* _pixmap; ///< pixmap
index bab229efaf151503ebb0db0ade08e92249e37a91..2343cb4c08fa300c242dc9bc2ba9e37535cad157 100644 (file)
@@ -168,52 +168,75 @@ PortMatrixGrid::render (cairo_t* cr)
 }
 
 
-void
-PortMatrixGrid::button_press (double x, double y, int b)
+PortMatrixNode
+PortMatrixGrid::position_to_node (double x, double y) const
 {
-       uint32_t grid_column = x / column_width ();
-       uint32_t grid_row = y / row_height ();
+       return PortMatrixNode (
+               position_to_channel (y, _body->row_ports().bundles(), row_height()),
+               position_to_channel (x, _body->column_ports().bundles(), column_width())
+               );
+}
 
-       boost::shared_ptr<ARDOUR::Bundle> our_bundle;
-       uint32_t our_channel = 0;
-       boost::shared_ptr<ARDOUR::Bundle> other_bundle;
-       uint32_t other_channel = 0;
 
-       ARDOUR::BundleList const r = _body->row_ports().bundles();
-       for (ARDOUR::BundleList::const_iterator i = r.begin(); i != r.end(); ++i) {
-               if (grid_row < (*i)->nchannels ()) {
-                       our_bundle = *i;
-                       our_channel = grid_row;
-                       break;
+PortMatrixBundleChannel
+PortMatrixGrid::position_to_channel (double p, ARDOUR::BundleList const& bundles, double inc) const
+{
+       uint32_t pos = p / inc;
+
+       for (ARDOUR::BundleList::const_iterator i = bundles.begin(); i != bundles.end(); ++i) {
+               if (pos < (*i)->nchannels()) {
+                       return PortMatrixBundleChannel (*i, pos);
                } else {
-                       grid_row -= (*i)->nchannels ();
+                       pos -= (*i)->nchannels();
                }
        }
+                       
+       return PortMatrixBundleChannel (boost::shared_ptr<ARDOUR::Bundle> (), 0);
+}
+
+
+double
+PortMatrixGrid::channel_position (
+       PortMatrixBundleChannel bc,
+       ARDOUR::BundleList const& bundles,
+       double inc) const
+{
+       double p = 0;
+       
+       ARDOUR::BundleList::const_iterator i = bundles.begin ();
+       while (i != bundles.end() && *i != bc.bundle) {
+               p += inc * (*i)->nchannels();
+               ++i;
+       }
 
-       ARDOUR::BundleList const c = _body->column_ports().bundles();
-       for (ARDOUR::BundleList::const_iterator i = c.begin(); i != c.end(); ++i) {
-               if (grid_column < (*i)->nchannels ()) {
-                       other_bundle = *i;
-                       other_channel = grid_column;
-                       break;
-               } else {
-                       grid_column -= (*i)->nchannels ();
-               }
+       if (i == bundles.end()) {
+               return 0;
        }
 
+       p += inc * bc.channel;
+
+       return p;
+}
+
+void
+PortMatrixGrid::button_press (double x, double y, int b)
+{
+       PortMatrixNode const node = position_to_node (x, y);
        
-       if (our_bundle && other_bundle) {
+       if (node.row.bundle && node.column.bundle) {
                
                PortMatrix::State const s = _port_matrix->get_state (
-                       our_bundle, our_channel, other_bundle, other_channel
+                       node.row.bundle, node.row.channel, node.column.bundle, node.column.channel
                        );
 
+               
                if (s == PortMatrix::ASSOCIATED || s == PortMatrix::NOT_ASSOCIATED) {
 
                        bool const n = !(s == PortMatrix::ASSOCIATED);
                        
                        _port_matrix->set_state (
-                               our_bundle, our_channel, other_bundle, other_channel,
+                               node.row.bundle, node.row.channel,
+                               node.column.bundle, node.column.channel,
                                n, 0
                                );
                }
@@ -223,4 +246,96 @@ PortMatrixGrid::button_press (double x, double y, int b)
        }
 }
 
+void
+PortMatrixGrid::draw_extra (cairo_t* cr)
+{
+       set_source_rgba (cr, mouseover_line_colour(), 0.3);
+       cairo_set_line_width (cr, mouseover_line_width());
+
+       if (_body->mouseover().row.bundle) {
+
+               double const y = component_to_parent_y (
+                       channel_position (_body->mouseover().row, _body->row_ports().bundles(), row_height()) + row_height() / 2
+                       );
+               
+               cairo_move_to (cr, _parent_rectangle.get_x(), y);
+               cairo_line_to (cr, _parent_rectangle.get_x() + _parent_rectangle.get_width(), y);
+               cairo_stroke (cr);
+       }
+
+       if (_body->mouseover().column.bundle) {
+
+               double const x = component_to_parent_x (
+                       channel_position (_body->mouseover().column, _body->column_ports().bundles(), column_width()) + column_width() / 2
+                       );
+               
+               cairo_move_to (cr, x, _parent_rectangle.get_y());
+               cairo_line_to (cr, x, _parent_rectangle.get_y() + _parent_rectangle.get_height());
+               cairo_stroke (cr);
+       }
+}
+
+void
+PortMatrixGrid::mouseover_changed (PortMatrixNode const& old)
+{
+       queue_draw_for (old);
+       queue_draw_for (_body->mouseover());
+}
+
+void
+PortMatrixGrid::mouseover_event (double x, double y)
+{
+       _body->set_mouseover (position_to_node (x, y));
+}
+
+void
+PortMatrixGrid::queue_draw_for (PortMatrixNode const &n)
+{
+       if (n.row.bundle) {
+
+               double const y = channel_position (n.row, _body->row_ports().bundles(), row_height());
+               _body->queue_draw_area (
+                       _parent_rectangle.get_x(),
+                       component_to_parent_y (y),
+                       _parent_rectangle.get_width(),
+                       row_height()
+                       );
+       }
+
+       if (n.column.bundle) {
+
+               double const x = channel_position (n.column, _body->column_ports().bundles(), column_width());
+               
+               _body->queue_draw_area (
+                       component_to_parent_x (x),
+                       _parent_rectangle.get_y(),
+                       column_width(),
+                       _parent_rectangle.get_height()
+                       );
+       }
+}
+
+double
+PortMatrixGrid::component_to_parent_x (double x) const
+{
+       return x - _body->xoffset() + _parent_rectangle.get_x();
+}
+
+double
+PortMatrixGrid::parent_to_component_x (double x) const
+{
+       return x + _body->xoffset() - _parent_rectangle.get_x();
+}
+
+double
+PortMatrixGrid::component_to_parent_y (double y) const
+{
+       return y - _body->yoffset() + _parent_rectangle.get_y();
+}
+
+double
+PortMatrixGrid::parent_to_component_y (double y) const
+{
+       return y + _body->yoffset() - _parent_rectangle.get_y();
+}
 
index 7441d3c79deea83e25a1f7a1861d62ef13760dfa..945ba5a2e6a0934fe028928205274e72520fa6f7 100644 (file)
@@ -23,7 +23,9 @@
 #include <string>
 #include <vector>
 #include <boost/shared_ptr.hpp>
+#include "ardour/types.h"
 #include "port_matrix_component.h"
+#include "port_matrix_types.h"
 
 class PortMatrix;
 class PortMatrixBody;
@@ -39,11 +41,25 @@ public:
        PortMatrixGrid (PortMatrix *, PortMatrixBody *);
 
        void button_press (double, double, int);
+       void mouseover_event (double, double);
+
+       double component_to_parent_x (double x) const;
+       double parent_to_component_x (double x) const;
+       double component_to_parent_y (double y) const;
+       double parent_to_component_y (double y) const;
+       void mouseover_changed (PortMatrixNode const &);
+       void draw_extra (cairo_t *);
 
 private:
+       
        void compute_dimensions ();
        void render (cairo_t *);
 
+       double channel_position (PortMatrixBundleChannel, ARDOUR::BundleList const &, double) const;
+       PortMatrixNode position_to_node (double, double) const;
+       PortMatrixBundleChannel position_to_channel (double, ARDOUR::BundleList const &, double) const;
+       void queue_draw_for (PortMatrixNode const &);
+
        PortMatrix* _port_matrix;
 };
 
index 7740d9cf18d1b726aedbbc4ab7194d9e277a82ec..278ae8e003a4b1694a1482d31430c38fdff06e2f 100644 (file)
@@ -111,13 +111,13 @@ PortMatrixRowLabels::render (cairo_t* cr)
        int g = 0;
        for (PortGroupList::const_iterator i = _body->row_ports().begin(); i != _body->row_ports().end(); ++i) {
 
-               if (!(*i)->visible() || ((*i)->bundles.empty() && (*i)->ports.empty()) ) {
+               if (!(*i)->visible() || ((*i)->bundles().empty() && (*i)->ports.empty()) ) {
                        continue;
                }
                        
                /* compute height of this group */
                double h = 0;
-               for (ARDOUR::BundleList::const_iterator j = (*i)->bundles.begin(); j != (*i)->bundles.end(); ++j) {
+               for (ARDOUR::BundleList::const_iterator j = (*i)->bundles().begin(); j != (*i)->bundles().end(); ++j) {
                        h += (*j)->nchannels() * row_height();
                }
                h += (*i)->ports.size() * row_height();
@@ -143,7 +143,7 @@ PortMatrixRowLabels::render (cairo_t* cr)
                ++g;
        }
 
-       /* SIDE BUNDLE NAMES */
+       /* BUNDLE NAMES */
 
        x = 0;
        if (_location == LEFT) {
@@ -182,41 +182,12 @@ PortMatrixRowLabels::render (cairo_t* cr)
        }
        
 
-       /* SIDE PORT NAMES */
+       /* PORT NAMES */
 
        y = 0;
        for (ARDOUR::BundleList::const_iterator i = r.begin(); i != r.end(); ++i) {
                for (uint32_t j = 0; j < (*i)->nchannels(); ++j) {
-
-                       double x = 0;
-                       if (_location == LEFT) {
-                               x = _longest_bundle_name + _highest_group_name + name_pad() * 4;
-                       } else if (_location == RIGHT) {
-                               x = 0;
-                       }
-
-                       Gdk::Color const colour = get_a_bundle_colour (i - r.begin ());
-                       set_source_rgb (cr, colour);
-                       cairo_rectangle (
-                               cr,
-                               x,
-                               y,
-                               _longest_port_name + (name_pad() * 2),
-                               row_height()
-                               );
-                       cairo_fill_preserve (cr);
-                       set_source_rgb (cr, background_colour());
-                       cairo_set_line_width (cr, label_border_width ());
-                       cairo_stroke (cr);
-
-                       cairo_text_extents_t ext;
-                       cairo_text_extents (cr, (*i)->channel_name(j).c_str(), &ext);
-                       double const off = (row_height() - ext.height) / 2;
-
-                       set_source_rgb (cr, text_colour());
-                       cairo_move_to (cr, x + name_pad(), y + name_pad() + off);
-                       cairo_show_text (cr, (*i)->channel_name(j).c_str());
-
+                       render_port_name (cr, get_a_bundle_colour (i - r.begin()), port_name_x(), y, PortMatrixBundleChannel (*i, j));
                        y += row_height();
                }
        }
@@ -305,3 +276,113 @@ PortMatrixRowLabels::rename_channel_proxy (boost::weak_ptr<ARDOUR::Bundle> b, ui
 
        _port_matrix->rename_channel (sb, c);
 }
+
+
+double
+PortMatrixRowLabels::component_to_parent_x (double x) const
+{
+       return x + _parent_rectangle.get_x();
+}
+
+double
+PortMatrixRowLabels::parent_to_component_x (double x) const
+{
+       return x - _parent_rectangle.get_x();
+}
+
+double
+PortMatrixRowLabels::component_to_parent_y (double y) const
+{
+       return y - _body->yoffset() + _parent_rectangle.get_y();
+}
+
+double
+PortMatrixRowLabels::parent_to_component_y (double y) const
+{
+       return y + _body->yoffset() - _parent_rectangle.get_y();
+}
+
+double
+PortMatrixRowLabels::port_name_x () const
+{
+       if (_location == LEFT) {
+               return _longest_bundle_name + _highest_group_name + name_pad() * 4;
+       } else if (_location == RIGHT) {
+               return 0;
+       }
+
+       return 0;
+}
+
+void
+PortMatrixRowLabels::render_port_name (
+       cairo_t* cr, Gdk::Color colour, double x, double y, PortMatrixBundleChannel const& bc
+       )
+{
+       set_source_rgb (cr, colour);
+       cairo_rectangle (cr, x, y, _longest_port_name + name_pad() * 2, row_height());
+       cairo_fill_preserve (cr);
+       set_source_rgb (cr, background_colour());
+       cairo_set_line_width (cr, label_border_width ());
+       cairo_stroke (cr);
+       
+       cairo_text_extents_t ext;
+       cairo_text_extents (cr, bc.bundle->channel_name(bc.channel).c_str(), &ext);
+       double const off = (row_height() - ext.height) / 2;
+       
+       set_source_rgb (cr, text_colour());
+       cairo_move_to (cr, x + name_pad(), y + name_pad() + off);
+       cairo_show_text (cr, bc.bundle->channel_name(bc.channel).c_str());
+}
+
+double
+PortMatrixRowLabels::channel_y (PortMatrixBundleChannel const& bc) const
+{
+       double y = 0;
+
+       ARDOUR::BundleList::const_iterator i = _body->row_ports().bundles().begin();
+       while (i != _body->row_ports().bundles().end() && *i != bc.bundle) {
+               y += row_height() * (*i)->nchannels();
+               ++i;
+       }
+
+       y += row_height() * bc.channel;
+
+       return y;
+}
+
+void
+PortMatrixRowLabels::queue_draw_for (PortMatrixNode const& n)
+{
+       if (n.row.bundle) {
+
+               _body->queue_draw_area (
+                       component_to_parent_x (port_name_x()),
+                       component_to_parent_y (channel_y (n.row)),
+                       _longest_port_name + name_pad() * 2,
+                       row_height()
+                       );
+       }
+
+}
+
+void
+PortMatrixRowLabels::mouseover_changed (PortMatrixNode const& old)
+{
+       queue_draw_for (old);
+       queue_draw_for (_body->mouseover());
+}
+
+void
+PortMatrixRowLabels::draw_extra (cairo_t* cr)
+{
+       if (_body->mouseover().row.bundle) {
+               render_port_name (
+                       cr,
+                       mouseover_port_colour (),
+                       component_to_parent_x (port_name_x()),
+                       component_to_parent_y (channel_y (_body->mouseover().row)),
+                       _body->mouseover().row
+                       );
+       }
+}
index dff6b71d26ad5d034401967ab1924a8b47ed148d..ce77dc82948f774d2a063a8d5a2453dd5c1f2685 100644 (file)
 #define __port_matrix_row_labels_h__
 
 #include <boost/shared_ptr.hpp>
+#include <gdkmm/color.h>
 #include "port_matrix_component.h"
 
 class PortMatrix;
 class PortMatrixBody;
+class PortMatrixNode;
+class PortMatrixBundleChannel;
 
 namespace ARDOUR {
        class Bundle;
@@ -47,11 +50,22 @@ public:
 
        void button_press (double, double, int, uint32_t);
   
+       double component_to_parent_x (double x) const;
+       double parent_to_component_x (double x) const;
+       double component_to_parent_y (double y) const;
+       double parent_to_component_y (double y) const;
+       void mouseover_changed (PortMatrixNode const &);
+       void draw_extra (cairo_t* cr);
+
 private:
        void render (cairo_t *);
        void compute_dimensions ();
        void remove_channel_proxy (boost::weak_ptr<ARDOUR::Bundle>, uint32_t);
        void rename_channel_proxy (boost::weak_ptr<ARDOUR::Bundle>, uint32_t);
+       void render_port_name (cairo_t *, Gdk::Color, double, double, PortMatrixBundleChannel const &);
+       double channel_y (PortMatrixBundleChannel const &) const;
+       void queue_draw_for (PortMatrixNode const &);
+       double port_name_x () const;
 
        PortMatrix* _port_matrix;
        double _longest_port_name;
diff --git a/gtk2_ardour/port_matrix_types.h b/gtk2_ardour/port_matrix_types.h
new file mode 100644 (file)
index 0000000..66dcf61
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+    Copyright (C) 2009 Paul Davis 
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef __ardour_gtk_port_matrix_types_h__
+#define __ardour_gtk_port_matrix_types_h__
+
+struct PortMatrixBundleChannel {
+       PortMatrixBundleChannel () : channel (0) {}
+       PortMatrixBundleChannel (boost::shared_ptr<ARDOUR::Bundle> b, uint32_t c)
+               : bundle (b), channel (c) {}
+       
+       bool operator== (PortMatrixBundleChannel const& other) const {
+               return bundle == other.bundle && channel == other.channel;
+       }
+       bool operator!= (PortMatrixBundleChannel const& other) const {
+               return bundle != other.bundle || channel != other.channel;
+       }
+       
+       boost::shared_ptr<ARDOUR::Bundle> bundle;
+       uint32_t channel;
+};
+
+struct PortMatrixNode {
+       PortMatrixNode () {}
+       PortMatrixNode (PortMatrixBundleChannel r, PortMatrixBundleChannel c) : row (r), column (c) {}
+       
+       bool operator== (PortMatrixNode const& other) const {
+               return row == other.row && column == other.column;
+       }
+       bool operator!= (PortMatrixNode const& other) const {
+               return row != other.row || column != other.column;
+       }
+       
+       PortMatrixBundleChannel row;
+       PortMatrixBundleChannel column;
+};
+
+#endif