From: Carl Hetherington Date: Tue, 17 Nov 2009 00:30:42 +0000 (+0000) Subject: The matrix used to highlight connections on click-hold on a row or column label;... X-Git-Tag: 3.0-alpha5~2796 X-Git-Url: https://main.carlh.net/gitweb/?a=commitdiff_plain;h=f2dbcec61d22f6e5aa483c9c787b660e691f85ad;p=ardour.git The matrix used to highlight connections on click-hold on a row or column label; now this happens, without a click, on any mouseover. Also mouseover a bundle name highlights everything connected to that bundle. Some cleanups along the way. git-svn-id: svn://localhost/ardour2/branches/3.0@6102 d708f5d6-7413-0410-9779-e7cbd77b26cf --- diff --git a/gtk2_ardour/port_matrix_body.cc b/gtk2_ardour/port_matrix_body.cc index 6696a67204..31f6d2be42 100644 --- a/gtk2_ardour/port_matrix_body.cc +++ b/gtk2_ardour/port_matrix_body.cc @@ -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::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::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::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::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::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::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 m; + m.push_back (n); + set_mouseover (m); +} + +void +PortMatrixBody::set_mouseover (list 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 old = _mouseover; + _mouseover = n; + + for (list::iterator i = _components.begin(); i != _components.end(); ++i) { + (*i)->mouseover_changed (old); + } } void diff --git a/gtk2_ardour/port_matrix_body.h b/gtk2_ardour/port_matrix_body.h index 341957a38a..c8dc0cce29 100644 --- a/gtk2_ardour/port_matrix_body.h +++ b/gtk2_ardour/port_matrix_body.h @@ -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 const &); + std::list mouseover () const { return _mouseover; } @@ -85,6 +87,7 @@ private: PortMatrixColumnLabels* _column_labels; PortMatrixRowLabels* _row_labels; PortMatrixGrid* _grid; + std::list _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 _mouseover; bool _ignore_component_size_changed; std::list _bundle_connections; diff --git a/gtk2_ardour/port_matrix_column_labels.cc b/gtk2_ardour/port_matrix_column_labels.cc index 5dcb710e7e..cfe6453fc7 100644 --- a/gtk2_ardour/port_matrix_column_labels.cc +++ b/gtk2_ardour/port_matrix_column_labels.cc @@ -215,11 +215,19 @@ PortMatrixColumnLabels::parent_to_component_y (double y) const } void -PortMatrixColumnLabels::mouseover_changed (PortMatrixNode const &) +PortMatrixColumnLabels::mouseover_changed (list const &) { - clear_channel_highlights (); - if (_body->mouseover().column.bundle && _body->mouseover().row.bundle) { - add_channel_highlight (_body->mouseover().column); + list const m = _body->mouseover (); + for (list::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, 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, ARDOUR::BundleChannel> gc = position_to_group_and_channel (cx / grid_spacing(), _matrix->columns()); + pair, 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, ARDOUR::BundleChannel> gc = position_to_group_and_channel (x, y, _matrix->columns()); - _matrix->popup_menu ( - gc, - make_pair (boost::shared_ptr (), ARDOUR::BundleChannel ()), - t - ); + if (b == 3) { + _matrix->popup_menu ( + gc, + make_pair (boost::shared_ptr (), ARDOUR::BundleChannel ()), + t + ); } } @@ -555,3 +566,37 @@ PortMatrixColumnLabels::draw_extra (cairo_t* cr) } } + +void +PortMatrixColumnLabels::motion (double x, double y) +{ + pair, 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 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)); + } +} diff --git a/gtk2_ardour/port_matrix_column_labels.h b/gtk2_ardour/port_matrix_column_labels.h index 5923bac4fc..e3c360cef0 100644 --- a/gtk2_ardour/port_matrix_column_labels.h +++ b/gtk2_ardour/port_matrix_column_labels.h @@ -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 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, ARDOUR::BundleChannel> position_to_group_and_channel (double, double, PortGroupList const *) const; void render (cairo_t *); void compute_dimensions (); diff --git a/gtk2_ardour/port_matrix_component.cc b/gtk2_ardour/port_matrix_component.cc index 7b83e5d10f..c617070907 100644 --- a/gtk2_ardour/port_matrix_component.cc +++ b/gtk2_ardour/port_matrix_component.cc @@ -192,8 +192,10 @@ PortMatrixComponent::channel_to_position (ARDOUR::BundleChannel bc, PortGroupLis pair, 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()) { diff --git a/gtk2_ardour/port_matrix_component.h b/gtk2_ardour/port_matrix_component.h index 3d9e5488b4..6a867f16e9 100644 --- a/gtk2_ardour/port_matrix_component.h +++ b/gtk2_ardour/port_matrix_component.h @@ -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 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; uint32_t channel_to_position (ARDOUR::BundleChannel, PortGroupList const *) const; - std::pair, ARDOUR::BundleChannel> position_to_group_and_channel (uint32_t, PortGroupList const *) const; + virtual std::pair, 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; diff --git a/gtk2_ardour/port_matrix_grid.cc b/gtk2_ardour/port_matrix_grid.cc index b6be4165a9..3b0a98e2f3 100644 --- a/gtk2_ardour/port_matrix_grid.cc +++ b/gtk2_ardour/port_matrix_grid.cc @@ -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, ARDOUR::BundleChannel> px = position_to_group_and_channel (x / grid_spacing(), _matrix->columns()); - pair, ARDOUR::BundleChannel> py = position_to_group_and_channel (y / grid_spacing(), _matrix->rows()); + pair, ARDOUR::BundleChannel> px = position_to_group_and_channel (x, y, _matrix->columns()); + pair, 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 const m = _body->mouseover (); - if (_body->mouseover().row.bundle && _body->mouseover().column.bundle) { + for (list::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 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 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::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); } diff --git a/gtk2_ardour/port_matrix_grid.h b/gtk2_ardour/port_matrix_grid.h index be4083c59a..c9b8d999e4 100644 --- a/gtk2_ardour/port_matrix_grid.h +++ b/gtk2_ardour/port_matrix_grid.h @@ -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 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, boost::shared_ptr, 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 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 nodes_on_line (int, int, int, int) const; diff --git a/gtk2_ardour/port_matrix_row_labels.cc b/gtk2_ardour/port_matrix_row_labels.cc index fdeaba77b6..0b8475cd03 100644 --- a/gtk2_ardour/port_matrix_row_labels.cc +++ b/gtk2_ardour/port_matrix_row_labels.cc @@ -133,32 +133,30 @@ PortMatrixRowLabels::render (cairo_t* cr) } } -void -PortMatrixRowLabels::button_press (double x, double y, int b, uint32_t t) +pair, 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, ARDOUR::BundleChannel> w = PortMatrixComponent::position_to_group_and_channel (p, o, _matrix->rows()); - pair, 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, 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 (), ARDOUR::BundleChannel ()), @@ -313,11 +311,19 @@ PortMatrixRowLabels::queue_draw_for (ARDOUR::BundleChannel const & bc) } void -PortMatrixRowLabels::mouseover_changed (PortMatrixNode const &) +PortMatrixRowLabels::mouseover_changed (list const &) { - clear_channel_highlights (); - if (_body->mouseover().column.bundle && _body->mouseover().row.bundle) { - add_channel_highlight (_body->mouseover().row); + list const m = _body->mouseover (); + for (list::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, 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 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 ())); + + } +} diff --git a/gtk2_ardour/port_matrix_row_labels.h b/gtk2_ardour/port_matrix_row_labels.h index 13e2747276..1610a9faa5 100644 --- a/gtk2_ardour/port_matrix_row_labels.h +++ b/gtk2_ardour/port_matrix_row_labels.h @@ -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 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); double channel_x (ARDOUR::BundleChannel const &) const; double channel_y (ARDOUR::BundleChannel const &) const; + virtual std::pair, ARDOUR::BundleChannel> position_to_group_and_channel (double, double, PortGroupList const *) const; void render (cairo_t *); void compute_dimensions ();