The matrix used to highlight connections on click-hold on a row or column label;...
authorCarl Hetherington <carl@carlh.net>
Tue, 17 Nov 2009 00:30:42 +0000 (00:30 +0000)
committerCarl Hetherington <carl@carlh.net>
Tue, 17 Nov 2009 00:30:42 +0000 (00:30 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@6102 d708f5d6-7413-0410-9779-e7cbd77b26cf

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.cc
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

index 6696a67204ff707792f7293f4da8977e421bd4b4..31f6d2be42b3f16fdd88cee249c34014b75107d8 100644 (file)
@@ -34,22 +34,25 @@ PortMatrixBody::PortMatrixBody (PortMatrix* p)
          _alloc_height (0),
          _xoffset (0),
          _yoffset (0),
-         _mouse_over_grid (false),
          _ignore_component_size_changed (false)
 {
        _column_labels = new PortMatrixColumnLabels (p, this);
        _row_labels = new PortMatrixRowLabels (p, this);
        _grid = new PortMatrixGrid (p, this);
 
+       _components.push_back (_column_labels);
+       _components.push_back (_row_labels);
+       _components.push_back (_grid);
+
        add_events (Gdk::LEAVE_NOTIFY_MASK | Gdk::POINTER_MOTION_MASK);
 }
 
 
 PortMatrixBody::~PortMatrixBody ()
 {
-       delete _column_labels;
-       delete _row_labels;
-       delete _grid;
+       for (list<PortMatrixComponent*>::iterator i = _components.begin(); i != _components.end(); ++i) {
+               delete *i;
+       }
 }
 
 bool
@@ -86,79 +89,40 @@ PortMatrixBody::on_expose_event (GdkEventExpose* event)
 
        bool intersects;
 
-       Gdk::Rectangle r = exposure;
-       /* the get_pixmap call may cause things to be rerendered and sizes to change,
-          so fetch the pixmap before calculating where to put it */
-       GdkPixmap* p = _column_labels->get_pixmap (get_window()->gobj());
-       r.intersect (_column_labels->parent_rectangle(), intersects);
-
-       if (intersects) {
-
-               gdk_draw_drawable (
-                       get_window()->gobj(),
-                       get_style()->get_fg_gc (Gtk::STATE_NORMAL)->gobj(),
-                       p,
-                       _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(),
-                       r.get_height()
-                       );
-       }
-
-       r = exposure;
-       p = _row_labels->get_pixmap (get_window()->gobj());
-       r.intersect (_row_labels->parent_rectangle(), intersects);
-
-       if (intersects) {
-               gdk_draw_drawable (
-                       get_window()->gobj(),
-                       get_style()->get_fg_gc (Gtk::STATE_NORMAL)->gobj(),
-                       p,
-                       _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(),
-                       r.get_height()
-                       );
-       }
+       for (list<PortMatrixComponent*>::iterator i = _components.begin(); i != _components.end(); ++i) {
+
+               Gdk::Rectangle r = exposure;
+
+               /* the get_pixmap call may cause things to be rerendered and sizes to change,
+                  so fetch the pixmap before calculating where to put it */
+               GdkPixmap* p = (*i)->get_pixmap (get_window()->gobj());
+               r.intersect ((*i)->parent_rectangle(), intersects);
+
+               if (intersects) {
+                       
+                       gdk_draw_drawable (
+                               get_window()->gobj(),
+                               get_style()->get_fg_gc (Gtk::STATE_NORMAL)->gobj(),
+                               p,
+                               (*i)->parent_to_component_x (r.get_x()),
+                               (*i)->parent_to_component_y (r.get_y()),
+                               r.get_x(),
+                               r.get_y(),
+                               r.get_width(),
+                               r.get_height()
+                               );
+               }
 
-       r = exposure;
-       p = _grid->get_pixmap (get_window()->gobj());
-       r.intersect (_grid->parent_rectangle(), intersects);
-
-       if (intersects) {
-               gdk_draw_drawable (
-                       get_window()->gobj(),
-                       get_style()->get_fg_gc (Gtk::STATE_NORMAL)->gobj(),
-                       p,
-                       _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(),
-                       r.get_height()
-                       );
        }
 
        cairo_t* cr = gdk_cairo_create (get_window()->gobj());
 
-       cairo_save (cr);
-       set_cairo_clip (cr, _grid->parent_rectangle ());
-       _grid->draw_extra (cr);
-       cairo_restore (cr);
-
-       cairo_save (cr);
-       set_cairo_clip (cr, _row_labels->parent_rectangle ());
-       _row_labels->draw_extra (cr);
-       cairo_restore (cr);
-
-       cairo_save (cr);
-       set_cairo_clip (cr, _column_labels->parent_rectangle ());
-       _column_labels->draw_extra (cr);
-       cairo_restore (cr);
+       for (list<PortMatrixComponent*>::iterator i = _components.begin(); i != _components.end(); ++i) {
+               cairo_save (cr);
+               set_cairo_clip (cr, (*i)->parent_rectangle ());
+               (*i)->draw_extra (cr);
+               cairo_restore (cr);
+       }
 
        cairo_destroy (cr);
 
@@ -295,9 +259,9 @@ PortMatrixBody::setup ()
                        );
        }
 
-       _column_labels->setup ();
-       _row_labels->setup ();
-       _grid->setup ();
+       for (list<PortMatrixComponent*>::iterator i = _components.begin(); i != _components.end(); ++i) {
+               (*i)->setup ();
+       }
 
        set_mouseover (PortMatrixNode ());
        
@@ -348,29 +312,14 @@ PortMatrixBody::set_yoffset (uint32_t yo)
 bool
 PortMatrixBody::on_button_press_event (GdkEventButton* ev)
 {
-       if (Gdk::Region (_grid->parent_rectangle()).point_in (ev->x, ev->y)) {
-
-               _grid->button_press (
-                       _grid->parent_to_component_x (ev->x),
-                       _grid->parent_to_component_y (ev->y),
-                       ev->button, ev->time
-                       );
-
-       } else if (Gdk::Region (_row_labels->parent_rectangle()).point_in (ev->x, ev->y)) {
-
-               _row_labels->button_press (
-                       _row_labels->parent_to_component_x (ev->x),
-                       _row_labels->parent_to_component_y (ev->y),
-                       ev->button, ev->time
-                       );
-
-       } else if (Gdk::Region (_column_labels->parent_rectangle()).point_in (ev->x, ev->y)) {
-
-               _column_labels->button_press (
-                       _column_labels->parent_to_component_x (ev->x),
-                       _column_labels->parent_to_component_y (ev->y),
-                       ev->button, ev->time
-                       );
+       for (list<PortMatrixComponent*>::iterator i = _components.begin(); i != _components.end(); ++i) {
+               if (Gdk::Region ((*i)->parent_rectangle()).point_in (ev->x, ev->y)) {
+                       (*i)->button_press (
+                               (*i)->parent_to_component_x (ev->x),
+                               (*i)->parent_to_component_y (ev->y),
+                               ev->button, ev->time
+                               );
+               }
        }
 
        return true;
@@ -379,13 +328,7 @@ PortMatrixBody::on_button_press_event (GdkEventButton* ev)
 bool
 PortMatrixBody::on_button_release_event (GdkEventButton* ev)
 {
-       if (Gdk::Region (_row_labels->parent_rectangle()).point_in (ev->x, ev->y) ||
-           Gdk::Region (_column_labels->parent_rectangle()).point_in (ev->x, ev->y)) {
-
-               _row_labels->clear_channel_highlights ();
-               _column_labels->clear_channel_highlights ();
-
-       } else if (Gdk::Region (_grid->parent_rectangle()).point_in (ev->x, ev->y)) {
+       if (Gdk::Region (_grid->parent_rectangle()).point_in (ev->x, ev->y)) {
 
                _grid->button_release (
                        _grid->parent_to_component_x (ev->x),
@@ -432,38 +375,59 @@ PortMatrixBody::on_leave_notify_event (GdkEventCrossing* ev)
 bool
 PortMatrixBody::on_motion_notify_event (GdkEventMotion* ev)
 {
-       if (Gdk::Region (_grid->parent_rectangle()).point_in (ev->x, ev->y)) {
-
-               _grid->motion (
-                       _grid->parent_to_component_x (ev->x),
-                       _grid->parent_to_component_y (ev->y)
-                       );
-
-               _mouse_over_grid = true;
-
-       } else {
-               if (_mouse_over_grid) {
-                       set_mouseover (PortMatrixNode ());
-                       _mouse_over_grid = false;
+       bool done = false;
+       
+       for (list<PortMatrixComponent*>::iterator i = _components.begin(); i != _components.end(); ++i) {
+               if (Gdk::Region ((*i)->parent_rectangle()).point_in (ev->x, ev->y)) {
+                       (*i)->motion (
+                               (*i)->parent_to_component_x (ev->x),
+                               (*i)->parent_to_component_y (ev->y)
+                               );
+
+                       done = true;
                }
        }
+                       
+
+       if (!done) {
+               set_mouseover (PortMatrixNode ());
+       }
 
        return true;
 }
 
 void
 PortMatrixBody::set_mouseover (PortMatrixNode const & n)
+{
+       list<PortMatrixNode> m;
+       m.push_back (n);
+       set_mouseover (m);
+}
+
+void
+PortMatrixBody::set_mouseover (list<PortMatrixNode> const & n)
 {
        if (n == _mouseover) {
                return;
        }
 
-       PortMatrixNode old = _mouseover;
-       _mouseover = n;
+       /* Channel highlights are set up only on mouseovers, so
+          it's reasonable to remove all channel highlights here.
+          We can't let individual components clear their own highlights
+          because of the case where, say, the row labels set up some column
+          highlights, and then we ask the column labels to set up their
+          own highlights and they clear them out before they start.
+       */
+
+       _row_labels->clear_channel_highlights ();
+       _column_labels->clear_channel_highlights ();
 
-       _grid->mouseover_changed (old);
-       _row_labels->mouseover_changed (old);
-       _column_labels->mouseover_changed (old);
+       list<PortMatrixNode> old = _mouseover;
+       _mouseover = n;
+       
+       for (list<PortMatrixComponent*>::iterator i = _components.begin(); i != _components.end(); ++i) {
+               (*i)->mouseover_changed (old);
+       }
 }
 
 void
index 341957a38a66e80a6e950a558aa0882cc7e975c3..c8dc0cce29f320934583455daf190b1e72b32dbc 100644 (file)
@@ -28,6 +28,7 @@ class PortMatrix;
 class PortMatrixColumnLabels;
 class PortMatrixRowLabels;
 class PortMatrixGrid;
+class PortMatrixComponent;
 
 /** The main body of the port matrix.  It is made up of three parts:
  *  column labels, grid and row labels, each drawn using cairo.
@@ -57,7 +58,8 @@ public:
        void rebuild_and_draw_grid ();
 
        void set_mouseover (PortMatrixNode const &);
-       PortMatrixNode mouseover () const {
+       void set_mouseover (std::list<PortMatrixNode> const &);
+       std::list<PortMatrixNode> mouseover () const {
                return _mouseover;
        }
 
@@ -85,6 +87,7 @@ private:
        PortMatrixColumnLabels* _column_labels;
        PortMatrixRowLabels* _row_labels;
        PortMatrixGrid* _grid;
+       std::list<PortMatrixComponent*> _components;
 
        uint32_t _alloc_width; ///< allocated width
        uint32_t _alloc_height; ///< allocated height
@@ -94,8 +97,7 @@ private:
        uint32_t _xoffset;
        uint32_t _yoffset;
 
-       PortMatrixNode _mouseover;
-       bool _mouse_over_grid;
+       std::list<PortMatrixNode> _mouseover;
        bool _ignore_component_size_changed;
 
        std::list<sigc::connection> _bundle_connections;
index 5dcb710e7e83b0764f63a74b359f72abb322642c..cfe6453fc70a0a8256ee7e0b3612d1774835625a 100644 (file)
@@ -215,11 +215,19 @@ PortMatrixColumnLabels::parent_to_component_y (double y) const
 }
 
 void
-PortMatrixColumnLabels::mouseover_changed (PortMatrixNode const &)
+PortMatrixColumnLabels::mouseover_changed (list<PortMatrixNode> const &)
 {
-       clear_channel_highlights ();
-       if (_body->mouseover().column.bundle && _body->mouseover().row.bundle) {
-               add_channel_highlight (_body->mouseover().column);
+       list<PortMatrixNode> const m = _body->mouseover ();
+       for (list<PortMatrixNode>::const_iterator i = m.begin(); i != m.end(); ++i) {
+
+               ARDOUR::BundleChannel c = i->column;
+               ARDOUR::BundleChannel r = i->row;
+               
+               if (c.bundle && r.bundle) {
+                       add_channel_highlight (c);
+               } else if (c.bundle) {
+                       _body->highlight_associated_channels (_matrix->column_index(), c);
+               }
        }
 }
 
@@ -447,46 +455,49 @@ PortMatrixColumnLabels::queue_draw_for (ARDOUR::BundleChannel const & bc)
        }
 }
 
-void
-PortMatrixColumnLabels::button_press (double x, double y, int b, uint32_t t)
+pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel>
+PortMatrixColumnLabels::position_to_group_and_channel (double p, double o, PortGroupList const * groups) const
 {
        uint32_t cx = 0;
        uint32_t const gh = _highest_group_name + 2 * name_pad();
 
        bool group_name = false;
        if (_matrix->arrangement() == PortMatrix::LEFT_TO_BOTTOM) {
-               if (y > (_height - gh)) {
+               if (o > (_height - gh)) {
                        group_name = true;
-                       cx = x;
+                       cx = p;
                } else {
-                       cx = x - (_height - gh - y) * tan (angle ());
+                       cx = p - (_height - gh - o) * tan (angle ());
                }
        } else {
-               if (y < gh) {
+               if (o < gh) {
                        group_name = true;
-                       cx = x - _overhang;
+                       cx = p - _overhang;
                } else {
-                       cx = x - (_height - y) * tan (angle ());
+                       cx = p - (_height - o) * tan (angle ());
                }
        }
 
-       pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel> gc = position_to_group_and_channel (cx / grid_spacing(), _matrix->columns());
+       pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel> w = PortMatrixComponent::position_to_group_and_channel (cx, o, groups);
 
-       if (b == 1) {
+       if (group_name) {
+               w.second.bundle.reset ();
+       }
 
-               if (group_name && gc.first) {
-                       gc.first->set_visible (!gc.first->visible ());
-               } else if (gc.second.bundle) {
-                       _body->highlight_associated_channels (_matrix->column_index(), gc.second);
-               }
+       return w;
+}
 
-       } else if (b == 3) {
+void
+PortMatrixColumnLabels::button_press (double x, double y, int b, uint32_t t)
+{
+       pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel> gc = position_to_group_and_channel (x, y, _matrix->columns());
 
-                       _matrix->popup_menu (
-                               gc,
-                               make_pair (boost::shared_ptr<PortGroup> (), ARDOUR::BundleChannel ()),
-                               t
-                               );
+       if (b == 3) {
+               _matrix->popup_menu (
+                       gc,
+                       make_pair (boost::shared_ptr<PortGroup> (), ARDOUR::BundleChannel ()),
+                       t
+                       );
        }
 }
 
@@ -555,3 +566,37 @@ PortMatrixColumnLabels::draw_extra (cairo_t* cr)
 
        }
 }
+
+void
+PortMatrixColumnLabels::motion (double x, double y)
+{
+       pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel> const w = position_to_group_and_channel (x, y, _matrix->columns());
+
+       if (w.second.bundle == 0) {
+               _body->set_mouseover (PortMatrixNode ());
+               return;
+       }
+
+       uint32_t const bh = _highest_group_name + _longest_channel_name * sin (angle ()) + _highest_text / cos (angle ());
+
+       if (
+               (_matrix->arrangement() == PortMatrix::LEFT_TO_BOTTOM && y > bh) ||
+               (_matrix->arrangement() == PortMatrix::TOP_TO_RIGHT && y < (_height - bh))
+               ) {
+
+               /* if the mouse is over a bundle name, highlight all channels in the bundle */
+               
+               list<PortMatrixNode> n;
+
+               for (uint32_t i = 0; i < w.second.bundle->nchannels(); ++i) {
+                       ARDOUR::BundleChannel const bc (w.second.bundle, i);
+                       n.push_back (PortMatrixNode (ARDOUR::BundleChannel (), bc));
+               }
+
+               _body->set_mouseover (n);
+
+       } else {
+       
+               _body->set_mouseover (PortMatrixNode (ARDOUR::BundleChannel (), w.second));
+       }
+}      
index 5923bac4fc0f6b77f02efcf388900b6c36cfb386..e3c360cef01139181d2540089d17a59c960bd595 100644 (file)
@@ -42,8 +42,9 @@ public:
        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 mouseover_changed (std::list<PortMatrixNode> const &);
        void draw_extra (cairo_t *);
+       void motion (double, double);
 
        uint32_t overhang () const {
                return _overhang;
@@ -55,6 +56,7 @@ private:
        double channel_x (ARDOUR::BundleChannel const &) const;
        double channel_y (ARDOUR::BundleChannel const &) const;
        void queue_draw_for (ARDOUR::BundleChannel const &);
+       std::pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel> position_to_group_and_channel (double, double, PortGroupList const *) const;
 
        void render (cairo_t *);
        void compute_dimensions ();
index 7b83e5d10f6c8adb6220488b2d152a9041e4afea..c617070907d9c464e3ef211c73c484559501d0b7 100644 (file)
@@ -192,8 +192,10 @@ PortMatrixComponent::channel_to_position (ARDOUR::BundleChannel bc, PortGroupLis
 
 
 pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel>
-PortMatrixComponent::position_to_group_and_channel (uint32_t p, PortGroupList const * groups) const
+PortMatrixComponent::position_to_group_and_channel (double p, double, PortGroupList const * groups) const
 {
+       p /= grid_spacing ();
+       
        PortGroupList::List::const_iterator i = groups->begin ();
 
        while (i != groups->end()) {
index 3d9e5488b4885b23eec83d0894ae0edee16381e2..6a867f16e95efefb832185c87767be1a4b2df57b 100644 (file)
@@ -47,8 +47,10 @@ public:
        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 mouseover_changed (std::list<PortMatrixNode> const &) = 0;
        virtual void draw_extra (cairo_t *) = 0;
+       virtual void button_press (double, double, int, uint32_t) {}
+       virtual void motion (double, double) {}
 
        void set_show_ports (bool);
        void setup ();
@@ -170,7 +172,7 @@ protected:
        void set_source_rgba (cairo_t *, Gdk::Color const &, double);
        uint32_t group_size (boost::shared_ptr<const PortGroup>) const;
        uint32_t channel_to_position (ARDOUR::BundleChannel, PortGroupList const *) const;
-       std::pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel> position_to_group_and_channel (uint32_t, PortGroupList const *) const;
+       virtual std::pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel> position_to_group_and_channel (double, double, PortGroupList const *) const;
 
        /** Render the complete component to a cairo context. */
        virtual void render (cairo_t *) = 0;
index b6be4165a9a03e7ea8066fbdb1b65c658573b717..3b0a98e2f3d2f22216edfc177917b81eb3eb3ee2 100644 (file)
@@ -260,19 +260,19 @@ PortMatrixGrid::draw_empty_square (cairo_t* cr, uint32_t x, uint32_t y)
 }
 
 PortMatrixNode
-PortMatrixGrid::position_to_node (uint32_t x, uint32_t y) const
+PortMatrixGrid::position_to_node (double x, double y) const
 {
        return PortMatrixNode (
-               position_to_group_and_channel (y, _matrix->rows()).second,
-               position_to_group_and_channel (x, _matrix->columns()).second
+               position_to_group_and_channel (y, x, _matrix->rows()).second,
+               position_to_group_and_channel (x, y, _matrix->columns()).second
                );
 }
 
 void
 PortMatrixGrid::button_press (double x, double y, int b, uint32_t t)
 {
-       pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel> px = position_to_group_and_channel (x / grid_spacing(), _matrix->columns());
-       pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel> py = position_to_group_and_channel (y / grid_spacing(), _matrix->rows());
+       pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel> px = position_to_group_and_channel (x, y, _matrix->columns());
+       pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel> py = position_to_group_and_channel (y, x, _matrix->rows());
 
        if (b == 1) {
 
@@ -295,7 +295,6 @@ PortMatrixGrid::get_association (PortMatrixNode node) const
 {
        if (_matrix->show_only_bundles()) {
 
-               bool have_unknown = false;
                bool have_off_diagonal_association = false;
                bool have_diagonal_association = false;
                bool have_diagonal_not_association = false;
@@ -399,7 +398,7 @@ PortMatrixGrid::button_release (double x, double y, int b, uint32_t /*t*/)
 
                } else {
 
-                       PortMatrixNode const n = position_to_node (x / grid_spacing(), y / grid_spacing());
+                       PortMatrixNode const n = position_to_node (x, y);
                        if (n.row.bundle && n.column.bundle) {
                                PortMatrixNode::State const s = get_association (n);
                                set_association (n, toggle_state (s));
@@ -420,26 +419,31 @@ PortMatrixGrid::draw_extra (cairo_t* cr)
        set_source_rgba (cr, mouseover_line_colour(), 0.3);
        cairo_set_line_width (cr, mouseover_line_width());
 
-       double const x = component_to_parent_x (channel_to_position (_body->mouseover().column, _matrix->columns()) * grid_spacing()) + grid_spacing() / 2;
-       double const y = component_to_parent_y (channel_to_position (_body->mouseover().row, _matrix->rows()) * grid_spacing()) + grid_spacing() / 2;
+       list<PortMatrixNode> const m = _body->mouseover ();
 
-       if (_body->mouseover().row.bundle && _body->mouseover().column.bundle) {
+       for (list<PortMatrixNode>::const_iterator i = m.begin(); i != m.end(); ++i) {
+       
+               double const x = component_to_parent_x (channel_to_position (i->column, _matrix->columns()) * grid_spacing()) + grid_spacing() / 2;
+               double const y = component_to_parent_y (channel_to_position (i->row, _matrix->rows()) * grid_spacing()) + grid_spacing() / 2;
 
-               cairo_move_to (cr, x, y);
-               if (_matrix->arrangement() == PortMatrix::LEFT_TO_BOTTOM) {
-                       cairo_line_to (cr, component_to_parent_x (0), y);
-               } else if (_matrix->arrangement() == PortMatrix::TOP_TO_RIGHT) {
-                       cairo_line_to (cr, _parent_rectangle.get_x() + _parent_rectangle.get_width(), y);
-               }
-               cairo_stroke (cr);
+               if (i->row.bundle && i->column.bundle) {
 
-               cairo_move_to (cr, x, y);
-               if (_matrix->arrangement() == PortMatrix::LEFT_TO_BOTTOM) {
-                       cairo_line_to (cr, x, _parent_rectangle.get_y() + _parent_rectangle.get_height());
-               } else if (_matrix->arrangement() == PortMatrix::TOP_TO_RIGHT) {
-                       cairo_line_to (cr, x, component_to_parent_y (0));
+                       cairo_move_to (cr, x, y);
+                       if (_matrix->arrangement() == PortMatrix::LEFT_TO_BOTTOM) {
+                               cairo_line_to (cr, component_to_parent_x (0), y);
+                       } else if (_matrix->arrangement() == PortMatrix::TOP_TO_RIGHT) {
+                               cairo_line_to (cr, _parent_rectangle.get_x() + _parent_rectangle.get_width(), y);
+                       }
+                       cairo_stroke (cr);
+                       
+                       cairo_move_to (cr, x, y);
+                       if (_matrix->arrangement() == PortMatrix::LEFT_TO_BOTTOM) {
+                               cairo_line_to (cr, x, _parent_rectangle.get_y() + _parent_rectangle.get_height());
+                       } else if (_matrix->arrangement() == PortMatrix::TOP_TO_RIGHT) {
+                               cairo_line_to (cr, x, component_to_parent_y (0));
+                       }
+                       cairo_stroke (cr);
                }
-               cairo_stroke (cr);
        }
 
        if (_dragging && _drag_valid && _moved) {
@@ -487,7 +491,7 @@ PortMatrixGrid::draw_extra (cairo_t* cr)
 }
 
 void
-PortMatrixGrid::mouseover_changed (PortMatrixNode const& old)
+PortMatrixGrid::mouseover_changed (list<PortMatrixNode> const & old)
 {
        queue_draw_for (old);
        queue_draw_for (_body->mouseover());
@@ -496,7 +500,7 @@ PortMatrixGrid::mouseover_changed (PortMatrixNode const& old)
 void
 PortMatrixGrid::motion (double x, double y)
 {
-       _body->set_mouseover (position_to_node (x / grid_spacing(), y / grid_spacing()));
+       _body->set_mouseover (position_to_node (x, y));
 
        int const px = x / grid_spacing ();
        int const py = y / grid_spacing ();
@@ -513,29 +517,32 @@ PortMatrixGrid::motion (double x, double y)
 }
 
 void
-PortMatrixGrid::queue_draw_for (PortMatrixNode const &n)
+PortMatrixGrid::queue_draw_for (list<PortMatrixNode> const &n)
 {
-       if (n.row.bundle) {
-
-               double const y = channel_to_position (n.row, _matrix->rows()) * grid_spacing ();
-               _body->queue_draw_area (
-                       _parent_rectangle.get_x(),
-                       component_to_parent_y (y),
-                       _parent_rectangle.get_width(),
-                       grid_spacing()
-                       );
-       }
-
-       if (n.column.bundle) {
+       for (list<PortMatrixNode>::const_iterator i = n.begin(); i != n.end(); ++i) {
+               
+               if (i->row.bundle) {
+
+                       double const y = channel_to_position (i->row, _matrix->rows()) * grid_spacing ();
+                       _body->queue_draw_area (
+                               _parent_rectangle.get_x(),
+                               component_to_parent_y (y),
+                               _parent_rectangle.get_width(),
+                               grid_spacing()
+                               );
+               }
 
-               double const x = channel_to_position (n.column, _matrix->columns()) * grid_spacing ();
+               if (i->column.bundle) {
 
-               _body->queue_draw_area (
-                       component_to_parent_x (x),
-                       _parent_rectangle.get_y(),
-                       grid_spacing(),
-                       _parent_rectangle.get_height()
-                       );
+                       double const x = channel_to_position (i->column, _matrix->columns()) * grid_spacing ();
+                       
+                       _body->queue_draw_area (
+                               component_to_parent_x (x),
+                               _parent_rectangle.get_y(),
+                               grid_spacing(),
+                               _parent_rectangle.get_height()
+                               );
+               }
        }
 }
 
@@ -600,12 +607,12 @@ PortMatrixGrid::nodes_on_line (int x0, int y0, int x1, int y1) const
 
        for (int x = x0; x <= x1; ++x) {
                if (steep) {
-                       PortMatrixNode n = position_to_node (y, x);
+                       PortMatrixNode n = position_to_node (y * grid_spacing (), x * grid_spacing ());
                        if (n.row.bundle && n.column.bundle) {
                                p.push_back (n);
                        }
                } else {
-                       PortMatrixNode n = position_to_node (x, y);
+                       PortMatrixNode n = position_to_node (x * grid_spacing (), y * grid_spacing ());
                        if (n.row.bundle && n.column.bundle) {
                                p.push_back (n);
                        }
index be4083c59aa0f7ffb803d8a350c5323194691450..c9b8d999e441c6d08180cba956f92cda2e1be1d6 100644 (file)
@@ -49,7 +49,7 @@ public:
        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 mouseover_changed (std::list<PortMatrixNode> const &);
        void draw_extra (cairo_t *);
 
 private:
@@ -58,8 +58,8 @@ private:
        void render (cairo_t *);
        void render_group_pair (cairo_t *, boost::shared_ptr<const PortGroup>, boost::shared_ptr<const PortGroup>, uint32_t, uint32_t);
 
-       PortMatrixNode position_to_node (uint32_t, uint32_t) const;
-       void queue_draw_for (PortMatrixNode const &);
+       PortMatrixNode position_to_node (double, double) const;
+       void queue_draw_for (std::list<PortMatrixNode> const &);
        void draw_association_indicator (cairo_t *, uint32_t, uint32_t, double p = 1);
        void draw_empty_square (cairo_t *, uint32_t, uint32_t);
        std::list<PortMatrixNode> nodes_on_line (int, int, int, int) const;
index fdeaba77b61a66dd190229b242b3c23a3c6c14e6..0b8475cd03e49f2fde599ef520ee511f4eec9c72 100644 (file)
@@ -133,32 +133,30 @@ PortMatrixRowLabels::render (cairo_t* cr)
        }
 }
 
-void
-PortMatrixRowLabels::button_press (double x, double y, int b, uint32_t t)
+pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel>
+PortMatrixRowLabels::position_to_group_and_channel (double p, double o, PortGroupList const * groups) const
 {
-       uint32_t const gw = (_highest_group_name + 2 * name_pad());
+       pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel> w = PortMatrixComponent::position_to_group_and_channel (p, o, _matrix->rows());
 
-       pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel> w = position_to_group_and_channel (y / grid_spacing (), _matrix->rows());
+       uint32_t const gw = (_highest_group_name + 2 * name_pad());
 
        if (
-               (_matrix->arrangement() == PortMatrix::LEFT_TO_BOTTOM && x < gw) ||
-               (_matrix->arrangement() == PortMatrix::TOP_TO_RIGHT && x > (_width - gw))
+               (_matrix->arrangement() == PortMatrix::LEFT_TO_BOTTOM && o < gw) ||
+               (_matrix->arrangement() == PortMatrix::TOP_TO_RIGHT && o > (_width - gw))
                ) {
 
                w.second.bundle.reset ();
        }
 
-       if (b == 1) {
+       return w;
+}
 
-               if (w.second.bundle) {
-                       _body->highlight_associated_channels (_matrix->row_index(), w.second);
-               } else {
-                       if (w.first) {
-                               w.first->set_visible (!w.first->visible());
-                       }
-               }
+void
+PortMatrixRowLabels::button_press (double x, double y, int b, uint32_t t)
+{
+       pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel> w = position_to_group_and_channel (y, x, _matrix->rows());
 
-       } else if (b == 3) {
+       if (b == 3) {
 
                _matrix->popup_menu (
                        make_pair (boost::shared_ptr<PortGroup> (), ARDOUR::BundleChannel ()),
@@ -313,11 +311,19 @@ PortMatrixRowLabels::queue_draw_for (ARDOUR::BundleChannel const & bc)
 }
 
 void
-PortMatrixRowLabels::mouseover_changed (PortMatrixNode const &)
+PortMatrixRowLabels::mouseover_changed (list<PortMatrixNode> const &)
 {
-       clear_channel_highlights ();
-       if (_body->mouseover().column.bundle && _body->mouseover().row.bundle) {
-               add_channel_highlight (_body->mouseover().row);
+       list<PortMatrixNode> const m = _body->mouseover ();
+       for (list<PortMatrixNode>::const_iterator i = m.begin(); i != m.end(); ++i) {
+               
+               ARDOUR::BundleChannel c = i->column;
+               ARDOUR::BundleChannel r = i->row;
+               
+               if (c.bundle && r.bundle) {
+                       add_channel_highlight (r);
+               } else if (r.bundle) {
+                       _body->highlight_associated_channels (_matrix->row_index(), r);
+               }
        }
 }
 
@@ -381,3 +387,40 @@ PortMatrixRowLabels::draw_extra (cairo_t* cr)
                ++g;
        }
 }
+
+void
+PortMatrixRowLabels::motion (double x, double y)
+{
+       pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel> const w = position_to_group_and_channel (y, x, _matrix->rows());
+
+       if (w.second.bundle == 0) {
+               /* not over any bundle */
+               _body->set_mouseover (PortMatrixNode ());
+               return;
+       }
+
+       uint32_t const bw = _highest_group_name + 2 * name_pad() + _longest_bundle_name + 2 * name_pad();
+
+       if (
+               (_matrix->arrangement() == PortMatrix::LEFT_TO_BOTTOM && x < bw) ||
+               (_matrix->arrangement() == PortMatrix::TOP_TO_RIGHT && x > (_width - bw))
+                
+                       ) {
+
+               /* if the mouse is over a bundle name, highlight all channels in the bundle */
+               
+               list<PortMatrixNode> n;
+
+               for (uint32_t i = 0; i < w.second.bundle->nchannels(); ++i) {
+                       ARDOUR::BundleChannel const bc (w.second.bundle, i);
+                       n.push_back (PortMatrixNode (bc, ARDOUR::BundleChannel ()));
+               }
+
+               _body->set_mouseover (n);
+
+       } else {
+       
+               _body->set_mouseover (PortMatrixNode (w.second, ARDOUR::BundleChannel ()));
+
+       }
+}
index 13e274727645a6905638c4196af341bced8a6b12..1610a9faa5b31137719ce3449b6a78bc870e1b6f 100644 (file)
@@ -49,14 +49,16 @@ public:
        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 mouseover_changed (std::list<PortMatrixNode> const &);
        void draw_extra (cairo_t *);
+       void motion (double, double);
 
 private:
        void render_channel_name (cairo_t *, Gdk::Color, Gdk::Color, double, double, ARDOUR::BundleChannel const &);
        void render_bundle_name (cairo_t *, Gdk::Color, Gdk::Color, double, double, boost::shared_ptr<ARDOUR::Bundle>);
        double channel_x (ARDOUR::BundleChannel const &) const;
        double channel_y (ARDOUR::BundleChannel const &) const;
+       virtual std::pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel> position_to_group_and_channel (double, double, PortGroupList const *) const;
 
        void render (cairo_t *);
        void compute_dimensions ();