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
This commit is contained in:
Carl Hetherington 2009-11-17 00:30:42 +00:00
parent 25ccf0f580
commit f2dbcec61d
10 changed files with 290 additions and 221 deletions

View file

@ -34,22 +34,25 @@ PortMatrixBody::PortMatrixBody (PortMatrix* p)
_alloc_height (0), _alloc_height (0),
_xoffset (0), _xoffset (0),
_yoffset (0), _yoffset (0),
_mouse_over_grid (false),
_ignore_component_size_changed (false) _ignore_component_size_changed (false)
{ {
_column_labels = new PortMatrixColumnLabels (p, this); _column_labels = new PortMatrixColumnLabels (p, this);
_row_labels = new PortMatrixRowLabels (p, this); _row_labels = new PortMatrixRowLabels (p, this);
_grid = new PortMatrixGrid (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); add_events (Gdk::LEAVE_NOTIFY_MASK | Gdk::POINTER_MOTION_MASK);
} }
PortMatrixBody::~PortMatrixBody () PortMatrixBody::~PortMatrixBody ()
{ {
delete _column_labels; for (list<PortMatrixComponent*>::iterator i = _components.begin(); i != _components.end(); ++i) {
delete _row_labels; delete *i;
delete _grid; }
} }
bool bool
@ -86,79 +89,40 @@ PortMatrixBody::on_expose_event (GdkEventExpose* event)
bool intersects; bool intersects;
Gdk::Rectangle r = exposure; for (list<PortMatrixComponent*>::iterator i = _components.begin(); i != _components.end(); ++i) {
/* 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::Rectangle r = exposure;
gdk_draw_drawable ( /* the get_pixmap call may cause things to be rerendered and sizes to change,
get_window()->gobj(), so fetch the pixmap before calculating where to put it */
get_style()->get_fg_gc (Gtk::STATE_NORMAL)->gobj(), GdkPixmap* p = (*i)->get_pixmap (get_window()->gobj());
p, r.intersect ((*i)->parent_rectangle(), intersects);
_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; if (intersects) {
p = _row_labels->get_pixmap (get_window()->gobj());
r.intersect (_row_labels->parent_rectangle(), 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()
);
}
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()
);
}
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_t* cr = gdk_cairo_create (get_window()->gobj());
cairo_save (cr); for (list<PortMatrixComponent*>::iterator i = _components.begin(); i != _components.end(); ++i) {
set_cairo_clip (cr, _grid->parent_rectangle ()); cairo_save (cr);
_grid->draw_extra (cr); set_cairo_clip (cr, (*i)->parent_rectangle ());
cairo_restore (cr); (*i)->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);
cairo_destroy (cr); cairo_destroy (cr);
@ -295,9 +259,9 @@ PortMatrixBody::setup ()
); );
} }
_column_labels->setup (); for (list<PortMatrixComponent*>::iterator i = _components.begin(); i != _components.end(); ++i) {
_row_labels->setup (); (*i)->setup ();
_grid->setup (); }
set_mouseover (PortMatrixNode ()); set_mouseover (PortMatrixNode ());
@ -348,29 +312,14 @@ PortMatrixBody::set_yoffset (uint32_t yo)
bool bool
PortMatrixBody::on_button_press_event (GdkEventButton* ev) PortMatrixBody::on_button_press_event (GdkEventButton* ev)
{ {
if (Gdk::Region (_grid->parent_rectangle()).point_in (ev->x, ev->y)) { for (list<PortMatrixComponent*>::iterator i = _components.begin(); i != _components.end(); ++i) {
if (Gdk::Region ((*i)->parent_rectangle()).point_in (ev->x, ev->y)) {
_grid->button_press ( (*i)->button_press (
_grid->parent_to_component_x (ev->x), (*i)->parent_to_component_x (ev->x),
_grid->parent_to_component_y (ev->y), (*i)->parent_to_component_y (ev->y),
ev->button, ev->time 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
);
} }
return true; return true;
@ -379,13 +328,7 @@ PortMatrixBody::on_button_press_event (GdkEventButton* ev)
bool bool
PortMatrixBody::on_button_release_event (GdkEventButton* ev) PortMatrixBody::on_button_release_event (GdkEventButton* ev)
{ {
if (Gdk::Region (_row_labels->parent_rectangle()).point_in (ev->x, ev->y) || if (Gdk::Region (_grid->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)) {
_grid->button_release ( _grid->button_release (
_grid->parent_to_component_x (ev->x), _grid->parent_to_component_x (ev->x),
@ -432,38 +375,59 @@ PortMatrixBody::on_leave_notify_event (GdkEventCrossing* ev)
bool bool
PortMatrixBody::on_motion_notify_event (GdkEventMotion* ev) PortMatrixBody::on_motion_notify_event (GdkEventMotion* ev)
{ {
if (Gdk::Region (_grid->parent_rectangle()).point_in (ev->x, ev->y)) { 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)
);
_grid->motion ( done = true;
_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;
} }
} }
if (!done) {
set_mouseover (PortMatrixNode ());
}
return true; return true;
} }
void void
PortMatrixBody::set_mouseover (PortMatrixNode const & n) 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) { if (n == _mouseover) {
return; return;
} }
PortMatrixNode old = _mouseover; /* Channel highlights are set up only on mouseovers, so
_mouseover = n; 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.
*/
_grid->mouseover_changed (old); _row_labels->clear_channel_highlights ();
_row_labels->mouseover_changed (old); _column_labels->clear_channel_highlights ();
_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 void

View file

@ -28,6 +28,7 @@ class PortMatrix;
class PortMatrixColumnLabels; class PortMatrixColumnLabels;
class PortMatrixRowLabels; class PortMatrixRowLabels;
class PortMatrixGrid; class PortMatrixGrid;
class PortMatrixComponent;
/** The main body of the port matrix. It is made up of three parts: /** The main body of the port matrix. It is made up of three parts:
* column labels, grid and row labels, each drawn using cairo. * column labels, grid and row labels, each drawn using cairo.
@ -57,7 +58,8 @@ public:
void rebuild_and_draw_grid (); void rebuild_and_draw_grid ();
void set_mouseover (PortMatrixNode const &); void set_mouseover (PortMatrixNode const &);
PortMatrixNode mouseover () const { void set_mouseover (std::list<PortMatrixNode> const &);
std::list<PortMatrixNode> mouseover () const {
return _mouseover; return _mouseover;
} }
@ -85,6 +87,7 @@ private:
PortMatrixColumnLabels* _column_labels; PortMatrixColumnLabels* _column_labels;
PortMatrixRowLabels* _row_labels; PortMatrixRowLabels* _row_labels;
PortMatrixGrid* _grid; PortMatrixGrid* _grid;
std::list<PortMatrixComponent*> _components;
uint32_t _alloc_width; ///< allocated width uint32_t _alloc_width; ///< allocated width
uint32_t _alloc_height; ///< allocated height uint32_t _alloc_height; ///< allocated height
@ -94,8 +97,7 @@ private:
uint32_t _xoffset; uint32_t _xoffset;
uint32_t _yoffset; uint32_t _yoffset;
PortMatrixNode _mouseover; std::list<PortMatrixNode> _mouseover;
bool _mouse_over_grid;
bool _ignore_component_size_changed; bool _ignore_component_size_changed;
std::list<sigc::connection> _bundle_connections; std::list<sigc::connection> _bundle_connections;

View file

@ -215,11 +215,19 @@ PortMatrixColumnLabels::parent_to_component_y (double y) const
} }
void void
PortMatrixColumnLabels::mouseover_changed (PortMatrixNode const &) PortMatrixColumnLabels::mouseover_changed (list<PortMatrixNode> const &)
{ {
clear_channel_highlights (); list<PortMatrixNode> const m = _body->mouseover ();
if (_body->mouseover().column.bundle && _body->mouseover().row.bundle) { for (list<PortMatrixNode>::const_iterator i = m.begin(); i != m.end(); ++i) {
add_channel_highlight (_body->mouseover().column);
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 pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel>
PortMatrixColumnLabels::button_press (double x, double y, int b, uint32_t t) PortMatrixColumnLabels::position_to_group_and_channel (double p, double o, PortGroupList const * groups) const
{ {
uint32_t cx = 0; uint32_t cx = 0;
uint32_t const gh = _highest_group_name + 2 * name_pad(); uint32_t const gh = _highest_group_name + 2 * name_pad();
bool group_name = false; bool group_name = false;
if (_matrix->arrangement() == PortMatrix::LEFT_TO_BOTTOM) { if (_matrix->arrangement() == PortMatrix::LEFT_TO_BOTTOM) {
if (y > (_height - gh)) { if (o > (_height - gh)) {
group_name = true; group_name = true;
cx = x; cx = p;
} else { } else {
cx = x - (_height - gh - y) * tan (angle ()); cx = p - (_height - gh - o) * tan (angle ());
} }
} else { } else {
if (y < gh) { if (o < gh) {
group_name = true; group_name = true;
cx = x - _overhang; cx = p - _overhang;
} else { } 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) { return w;
gc.first->set_visible (!gc.first->visible ()); }
} else if (gc.second.bundle) {
_body->highlight_associated_channels (_matrix->column_index(), gc.second);
}
} 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 ( if (b == 3) {
gc, _matrix->popup_menu (
make_pair (boost::shared_ptr<PortGroup> (), ARDOUR::BundleChannel ()), gc,
t 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));
}
}

View file

@ -42,8 +42,9 @@ public:
double parent_to_component_x (double x) const; double parent_to_component_x (double x) const;
double component_to_parent_y (double y) const; double component_to_parent_y (double y) const;
double parent_to_component_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 draw_extra (cairo_t *);
void motion (double, double);
uint32_t overhang () const { uint32_t overhang () const {
return _overhang; return _overhang;
@ -55,6 +56,7 @@ private:
double channel_x (ARDOUR::BundleChannel const &) const; double channel_x (ARDOUR::BundleChannel const &) const;
double channel_y (ARDOUR::BundleChannel const &) const; double channel_y (ARDOUR::BundleChannel const &) const;
void queue_draw_for (ARDOUR::BundleChannel 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 render (cairo_t *);
void compute_dimensions (); void compute_dimensions ();

View file

@ -192,8 +192,10 @@ PortMatrixComponent::channel_to_position (ARDOUR::BundleChannel bc, PortGroupLis
pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel> 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 (); PortGroupList::List::const_iterator i = groups->begin ();
while (i != groups->end()) { while (i != groups->end()) {

View file

@ -47,8 +47,10 @@ public:
virtual double parent_to_component_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 component_to_parent_y (double y) const = 0;
virtual double parent_to_component_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 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 set_show_ports (bool);
void setup (); void setup ();
@ -170,7 +172,7 @@ protected:
void set_source_rgba (cairo_t *, Gdk::Color const &, double); void set_source_rgba (cairo_t *, Gdk::Color const &, double);
uint32_t group_size (boost::shared_ptr<const PortGroup>) const; uint32_t group_size (boost::shared_ptr<const PortGroup>) const;
uint32_t channel_to_position (ARDOUR::BundleChannel, PortGroupList const *) 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. */ /** Render the complete component to a cairo context. */
virtual void render (cairo_t *) = 0; virtual void render (cairo_t *) = 0;

View file

@ -260,19 +260,19 @@ PortMatrixGrid::draw_empty_square (cairo_t* cr, uint32_t x, uint32_t y)
} }
PortMatrixNode PortMatrixNode
PortMatrixGrid::position_to_node (uint32_t x, uint32_t y) const PortMatrixGrid::position_to_node (double x, double y) const
{ {
return PortMatrixNode ( return PortMatrixNode (
position_to_group_and_channel (y, _matrix->rows()).second, position_to_group_and_channel (y, x, _matrix->rows()).second,
position_to_group_and_channel (x, _matrix->columns()).second position_to_group_and_channel (x, y, _matrix->columns()).second
); );
} }
void void
PortMatrixGrid::button_press (double x, double y, int b, uint32_t t) 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> px = position_to_group_and_channel (x, y, _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> py = position_to_group_and_channel (y, x, _matrix->rows());
if (b == 1) { if (b == 1) {
@ -295,7 +295,6 @@ PortMatrixGrid::get_association (PortMatrixNode node) const
{ {
if (_matrix->show_only_bundles()) { if (_matrix->show_only_bundles()) {
bool have_unknown = false;
bool have_off_diagonal_association = false; bool have_off_diagonal_association = false;
bool have_diagonal_association = false; bool have_diagonal_association = false;
bool have_diagonal_not_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 { } 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) { if (n.row.bundle && n.column.bundle) {
PortMatrixNode::State const s = get_association (n); PortMatrixNode::State const s = get_association (n);
set_association (n, toggle_state (s)); 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); set_source_rgba (cr, mouseover_line_colour(), 0.3);
cairo_set_line_width (cr, mouseover_line_width()); 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; list<PortMatrixNode> const m = _body->mouseover ();
double const y = component_to_parent_y (channel_to_position (_body->mouseover().row, _matrix->rows()) * grid_spacing()) + grid_spacing() / 2;
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 (i->row.bundle && i->column.bundle) {
if (_matrix->arrangement() == PortMatrix::LEFT_TO_BOTTOM) {
cairo_line_to (cr, component_to_parent_x (0), y); cairo_move_to (cr, x, y);
} else if (_matrix->arrangement() == PortMatrix::TOP_TO_RIGHT) { if (_matrix->arrangement() == PortMatrix::LEFT_TO_BOTTOM) {
cairo_line_to (cr, _parent_rectangle.get_x() + _parent_rectangle.get_width(), y); 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);
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);
} }
if (_dragging && _drag_valid && _moved) { if (_dragging && _drag_valid && _moved) {
@ -487,7 +491,7 @@ PortMatrixGrid::draw_extra (cairo_t* cr)
} }
void void
PortMatrixGrid::mouseover_changed (PortMatrixNode const& old) PortMatrixGrid::mouseover_changed (list<PortMatrixNode> const & old)
{ {
queue_draw_for (old); queue_draw_for (old);
queue_draw_for (_body->mouseover()); queue_draw_for (_body->mouseover());
@ -496,7 +500,7 @@ PortMatrixGrid::mouseover_changed (PortMatrixNode const& old)
void void
PortMatrixGrid::motion (double x, double y) 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 px = x / grid_spacing ();
int const py = y / grid_spacing (); int const py = y / grid_spacing ();
@ -513,29 +517,32 @@ PortMatrixGrid::motion (double x, double y)
} }
void void
PortMatrixGrid::queue_draw_for (PortMatrixNode const &n) PortMatrixGrid::queue_draw_for (list<PortMatrixNode> const &n)
{ {
if (n.row.bundle) { for (list<PortMatrixNode>::const_iterator i = n.begin(); i != n.end(); ++i) {
if (i->row.bundle) {
double const y = channel_to_position (n.row, _matrix->rows()) * grid_spacing (); double const y = channel_to_position (i->row, _matrix->rows()) * grid_spacing ();
_body->queue_draw_area ( _body->queue_draw_area (
_parent_rectangle.get_x(), _parent_rectangle.get_x(),
component_to_parent_y (y), component_to_parent_y (y),
_parent_rectangle.get_width(), _parent_rectangle.get_width(),
grid_spacing() grid_spacing()
); );
} }
if (n.column.bundle) { if (i->column.bundle) {
double const x = channel_to_position (n.column, _matrix->columns()) * grid_spacing (); double const x = channel_to_position (i->column, _matrix->columns()) * grid_spacing ();
_body->queue_draw_area ( _body->queue_draw_area (
component_to_parent_x (x), component_to_parent_x (x),
_parent_rectangle.get_y(), _parent_rectangle.get_y(),
grid_spacing(), grid_spacing(),
_parent_rectangle.get_height() _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) { for (int x = x0; x <= x1; ++x) {
if (steep) { 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) { if (n.row.bundle && n.column.bundle) {
p.push_back (n); p.push_back (n);
} }
} else { } 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) { if (n.row.bundle && n.column.bundle) {
p.push_back (n); p.push_back (n);
} }

View file

@ -49,7 +49,7 @@ public:
double parent_to_component_x (double x) const; double parent_to_component_x (double x) const;
double component_to_parent_y (double y) const; double component_to_parent_y (double y) const;
double parent_to_component_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 draw_extra (cairo_t *);
private: private:
@ -58,8 +58,8 @@ private:
void render (cairo_t *); void render (cairo_t *);
void render_group_pair (cairo_t *, boost::shared_ptr<const PortGroup>, boost::shared_ptr<const PortGroup>, uint32_t, uint32_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; PortMatrixNode position_to_node (double, double) const;
void queue_draw_for (PortMatrixNode const &); void queue_draw_for (std::list<PortMatrixNode> const &);
void draw_association_indicator (cairo_t *, uint32_t, uint32_t, double p = 1); void draw_association_indicator (cairo_t *, uint32_t, uint32_t, double p = 1);
void draw_empty_square (cairo_t *, uint32_t, uint32_t); void draw_empty_square (cairo_t *, uint32_t, uint32_t);
std::list<PortMatrixNode> nodes_on_line (int, int, int, int) const; std::list<PortMatrixNode> nodes_on_line (int, int, int, int) const;

View file

@ -133,32 +133,30 @@ PortMatrixRowLabels::render (cairo_t* cr)
} }
} }
void pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel>
PortMatrixRowLabels::button_press (double x, double y, int b, uint32_t t) PortMatrixRowLabels::position_to_group_and_channel (double p, double o, PortGroupList const * groups) const
{ {
pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel> w = PortMatrixComponent::position_to_group_and_channel (p, o, _matrix->rows());
uint32_t const gw = (_highest_group_name + 2 * name_pad()); uint32_t const gw = (_highest_group_name + 2 * name_pad());
pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel> w = position_to_group_and_channel (y / grid_spacing (), _matrix->rows());
if ( if (
(_matrix->arrangement() == PortMatrix::LEFT_TO_BOTTOM && x < gw) || (_matrix->arrangement() == PortMatrix::LEFT_TO_BOTTOM && o < gw) ||
(_matrix->arrangement() == PortMatrix::TOP_TO_RIGHT && x > (_width - gw)) (_matrix->arrangement() == PortMatrix::TOP_TO_RIGHT && o > (_width - gw))
) { ) {
w.second.bundle.reset (); w.second.bundle.reset ();
} }
if (b == 1) { return w;
}
if (w.second.bundle) { void
_body->highlight_associated_channels (_matrix->row_index(), w.second); PortMatrixRowLabels::button_press (double x, double y, int b, uint32_t t)
} else { {
if (w.first) { pair<boost::shared_ptr<PortGroup>, ARDOUR::BundleChannel> w = position_to_group_and_channel (y, x, _matrix->rows());
w.first->set_visible (!w.first->visible());
}
}
} else if (b == 3) { if (b == 3) {
_matrix->popup_menu ( _matrix->popup_menu (
make_pair (boost::shared_ptr<PortGroup> (), ARDOUR::BundleChannel ()), make_pair (boost::shared_ptr<PortGroup> (), ARDOUR::BundleChannel ()),
@ -313,11 +311,19 @@ PortMatrixRowLabels::queue_draw_for (ARDOUR::BundleChannel const & bc)
} }
void void
PortMatrixRowLabels::mouseover_changed (PortMatrixNode const &) PortMatrixRowLabels::mouseover_changed (list<PortMatrixNode> const &)
{ {
clear_channel_highlights (); list<PortMatrixNode> const m = _body->mouseover ();
if (_body->mouseover().column.bundle && _body->mouseover().row.bundle) { for (list<PortMatrixNode>::const_iterator i = m.begin(); i != m.end(); ++i) {
add_channel_highlight (_body->mouseover().row);
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; ++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 ()));
}
}

View file

@ -49,14 +49,16 @@ public:
double parent_to_component_x (double x) const; double parent_to_component_x (double x) const;
double component_to_parent_y (double y) const; double component_to_parent_y (double y) const;
double parent_to_component_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 draw_extra (cairo_t *);
void motion (double, double);
private: private:
void render_channel_name (cairo_t *, Gdk::Color, Gdk::Color, double, double, ARDOUR::BundleChannel const &); 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>); 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_x (ARDOUR::BundleChannel const &) const;
double channel_y (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 render (cairo_t *);
void compute_dimensions (); void compute_dimensions ();